from collections import OrderedDict

from faker.utils.decorators import slugify

from .. import Provider as InternetProvider


class Provider(InternetProvider):
    user_name_formats = (
        "{{last_romanized_name}}.{{first_romanized_name}}",
        "{{first_romanized_name}}.{{last_romanized_name}}",
        "{{first_romanized_name}}##",
        "?{{last_romanized_name}}",
    )

    tlds = OrderedDict(
        (
            ("cn", 0.8),
            ("net", 0.1),
            ("com", 0.05),
            ("org", 0.05),
        )
    )

    second_level_domains = (
        "ac",
        "com",
        "edu",
        "gov",
        "mil",
        "net",
        "org",
        "ah",
        "bj",
        "cq",
        "fj",
        "gd",
        "gs",
        "gz",
        "gx",
        "ha",
        "hb",
        "he",
        "hi",
        "hk",
        "hl",
        "hn",
        "jl",
        "js",
        "jx",
        "ln",
        "mo",
        "nm",
        "nx",
        "qh",
        "sc",
        "sd",
        "sh",
        "sn",
        "sx",
        "tj",
        "xj",
        "xz",
        "yn",
        "zj",
    )

    domain_formats = (
        "##",
        "??",
        "{{first_romanized_name}}",
        "{{last_romanized_name}}",
        "{{first_romanized_name}}{{last_romanized_name}}",
        "{{last_romanized_name}}{{last_romanized_name}}",
        "{{first_romanized_name}}{{first_romanized_name}}",
    )

    @slugify
    def domain_word(self) -> str:
        pattern: str = self.random_element(self.domain_formats)
        if "#" in pattern or "?" in pattern:
            return self.bothify(pattern)
        else:
            return self.generator.parse(pattern)

    def domain_name(self, levels: int = 1) -> str:
        if levels < 1:
            raise ValueError("levels must be greater than or equal to 1")
        if levels == 1:
            domain_word = self.domain_word()
            # Avoids he.cn as seen in issue #687
            while domain_word in self.second_level_domains:
                domain_word = self.domain_word()
            return domain_word + "." + self.tld()
        elif levels == 2:
            my_tld = self.tld()
            if my_tld == "cn":
                my_second_level: str = self.random_element(self.second_level_domains)
            else:
                my_second_level = self.domain_word()
            return self.domain_word() + "." + my_second_level + "." + my_tld
        else:
            return self.domain_word() + "." + self.domain_name(levels - 1)
