from test.support import open_urlresource
import unittest
from http.client import HTTPException
import sys
from unicodedata import normalize, unidata_version
TESTDATAFILE = 'NormalizationTest.txt'
TESTDATAURL = ('http://www.pythontest.net/unicode/' + unidata_version + '/' +
    TESTDATAFILE)


def check_version(testfile):
    hdr = testfile.readline()
    return unidata_version in hdr


class RangeError(Exception):
    pass


def NFC(str):
    return normalize('NFC', str)


def NFKC(str):
    return normalize('NFKC', str)


def NFD(str):
    return normalize('NFD', str)


def NFKD(str):
    return normalize('NFKD', str)


def unistr(data):
    data = [int(x, 16) for x in data.split(' ')]
    for x in data:
        if x > sys.maxunicode:
            raise RangeError
    return ''.join([chr(x) for x in data])


class NormalizationTest(unittest.TestCase):

    def test_main(self):
        part = None
        part1_data = {}
        try:
            testdata = open_urlresource(TESTDATAURL, encoding='utf-8',
                check=check_version)
        except (OSError, HTTPException):
            self.skipTest('Could not retrieve ' + TESTDATAURL)
        self.addCleanup(testdata.close)
        for line in testdata:
            if '#' in line:
                line = line.split('#')[0]
            line = line.strip()
            if not line:
                continue
            if line.startswith('@Part'):
                part = line.split()[0]
                continue
            try:
                c1, c2, c3, c4, c5 = [unistr(x) for x in line.split(';')[:-1]]
            except RangeError:
                if part == '@Part1':
                    try:
                        c1 = unistr(line.split(';')[0])
                    except RangeError:
                        pass
                    else:
                        part1_data[c1] = 1
                continue
            self.assertTrue(c2 == NFC(c1) == NFC(c2) == NFC(c3), line)
            self.assertTrue(c4 == NFC(c4) == NFC(c5), line)
            self.assertTrue(c3 == NFD(c1) == NFD(c2) == NFD(c3), line)
            self.assertTrue(c5 == NFD(c4) == NFD(c5), line)
            self.assertTrue(c4 == NFKC(c1) == NFKC(c2) == NFKC(c3) == NFKC(
                c4) == NFKC(c5), line)
            self.assertTrue(c5 == NFKD(c1) == NFKD(c2) == NFKD(c3) == NFKD(
                c4) == NFKD(c5), line)
            if part == '@Part1':
                part1_data[c1] = 1
        for c in range(sys.maxunicode + 1):
            X = chr(c)
            if X in part1_data:
                continue
            self.assertTrue(X == NFC(X) == NFD(X) == NFKC(X) == NFKD(X), c)

    def test_bug_834676(self):
        normalize('NFC', '한글')


if __name__ == '__main__':
    unittest.main()
