# coding=utf8
from __future__ import unicode_literals, absolute_import, print_function

from . import docstring

import unittest
import random
import string


class Generate(object):

    _space_count = 8

    def __init__(self, conf, text, pre, post, s):
        self.conf = conf
        self.text = text
        self.pre = pre
        self.post = post
        self.s = s

        s1, s2, s3, s4, s5, s6, s7, s8 = s
        self.beg = ''.join(["{-#", s1, "Straight", s2, "Configuration", s3, s8.join(conf), s4, '#-}'])
        self.end = ''.join(['{-#', s5, 'Straight', s6, 'End', s7, '#-}'])

        self.doc = ''.join([pre, self.beg, text, self.end, post])

    normal_pragma_list = [
        "{-##-}",
        "{-# #-}",
        "{-#\n#-}",
        "{-#A#-}",
        "{-#A #-}",
        "{-# A#-}",
        "{-# A #-}",
        "{-#A\n#-}",
        "{-#\nB#-}",
        "{-#A\nB#-}",
    ]

    @classmethod
    def random_config(cls):
        def word():
            return ''.join([random.choice(string.ascii_letters) for _ in range(random.randrange(3, 10))])
        ws = [word() for _ in range(random.randrange(1, 5))]
        return ws

    @classmethod
    def random_space(cls):
        l = random.randrange(1, 10)
        c = ''.join([random.choice(' \n\t') for c in range(l)])
        return c

    @classmethod
    def random_text(cls):
        charset = string.printable
        l = random.randrange(20)
        c = ''.join([random.choice(charset) for c in range(l)])
        while True:
            nc = c.replace('{-#', '').replace('#-}', '')
            if c == nc:
                break
            c = nc
        return c

    @classmethod
    def random(cls):
        conf = cls.random_config()
        pre = cls.random_text()
        post = cls.random_text()
        text_list = []
        for i in range(random.randrange(5)):
            if random.choice([False, True]):
                text_list.append(cls.random_text())
            else:
                text_list.append(random.choice(cls.normal_pragma_list))
        text = ''.join(text_list)
        s = [cls.random_space() for _ in range(cls._space_count)]
        return Generate(conf=conf, text=text, pre=pre, post=post, s=s)

    def validate(self):
        ds = docstring.DocString.parse(self.doc)
        assert ds.conf_args == self.conf, (
            repr(ds.conf_args), repr(self.conf)
        )
        assert ds.straight_text.strip() == (self.beg + self.text + self.end).strip(), (
            repr(ds.straight_text), repr(self.beg), repr(self.text), repr(self.end)
        )

        assert ds.rest_text.strip().startswith(self.pre.strip()), (ds.rest_text, self.pre)
        assert ds.rest_text.strip().endswith(self.post.strip()), (ds.rest_text, self.post)


class TestParse(unittest.TestCase):

    def once(self):
        d = Generate.random()
        d.validate()

    def test_main(self):
        for _ in range(10000):
            self.once()
