from http import HTTPStatus
from dataclasses import dataclass
from .glpi_utils import sha1

@dataclass
class StaticFile:
    NOT_FOUND = 0
    EXISTS = 1

class GlpiStaticFilesVersion:
    """
    Class that gather all version and files that has been modified
    from glpi 10.0.0 to latest version of glpi
    """
    STATIC_FILES_VERSION = {
        "10.0.0": {
            "js/Forms/FaIconSelector.js": "31440690bc98e669023548bd9ff47c03f80bae93",
            "js/RichText/ContentTemplatesParameters.js": "7a52232febba99d6ee5d77fda897d483ad414ce9",
            "js/RichText/UserMention.js": "49b9f47e7198723e8e3cc40f3a79b812fe9033be"
        },
        "10.0.1": {
            "js/Forms/FaIconSelector.js": "14f368a22d3b4a5821f67faf3fd9ede5e1cb6583",
            "js/RichText/ContentTemplatesParameters.js": "940da7c1bedd78d46a51b55d5ecb53e90d7cb59c",
            "js/modules/Kanban/Kanban.js": "ae6411ac4599f567f2b1bbf98ae55d35d6d917b6"
        },
        "10.0.2": {
            "js/modules/Kanban/Kanban.js": "d0386ea1703e0b49b46440fb20c10c77be76f197",
            "js/common.js": "c45dd1752057aa49582b6d086373f202b8ecaf0f",
            "js/fileupload.js": "d576224682a28fac94a277bcf7e71ef3747fc5ab"
        },
        "10.0.3": {
            "js/common.js": "0f8b033ed14dc7d1c72101022d5deeb319310fa6",
            "js/fileupload.js": "652ca90f1dcfbb51ac9bc20e7df8aeb3899d9cfa",
            "js/impact.js": "c0dec7529eda3bf5f9b769369b572dbdc81a2588"
        },
        "10.0.4": {
            "js/common.js": "35c8b03170a66e7429c862a920800ab5882bdda4",
            "js/dashboard.js": "0959880f62c98022c1254eaa436d0f78932211e3",
            "js/fileupload.js": "3a135fd45ecd15bcef9240393b5777a101f252a4"
        },
        "10.0.5": {
            "js/Forms/FaIconSelector.js": "14f368a22d3b4a5821f67faf3fd9ede5e1cb6583",
            "js/RichText/ContentTemplatesParameters.js": "940da7c1bedd78d46a51b55d5ecb53e90d7cb59c"
        },
        "10.0.6": {
            "js/Forms/FaIconSelector.js": "b190061923d1d0fef224d6d47a845e912988bc7b",
            "js/RichText/ContentTemplatesParameters.js": "caaa28a34c2f0c53fdee1e958b1d0777b90131fd",
            "js/fileupload.js": "3181326791c9b2438ccae45452e39d697a570a40"
        },
        "10.0.7": {
            "js/common.js": "4d90fb75e30b84502bbf4a14131da987f1327a5b",
            "js/dashboard.js": "cfe35fb62edfdd713f4110833effb53dbfc001b5",
            "js/fileupload.js": "c68872daac04eb8959b210c970a922e5aaffaee3"
        },
        "10.0.8": {
            "js/common.js": "0d298299d0a94f010b3e7f0f292b87382203f94b",
            "js/dashboard.js": "65cd05628bba57e833a8aef8560e75d0840af0c9",
            "js/glpi_dialog.js": "87db9b200df67473cc7f4e233b554aea8f9b9b98"
        },
        "10.0.9": {
            "js/dashboard.js": "65cd05628bba57e833a8aef8560e75d0840af0c9",
            "js/fileupload.js": "c68872daac04eb8959b210c970a922e5aaffaee3",
            "js/modules/Kanban/Kanban.js": "d451bf837532b399f3046091d792cf2bc5035a9a"
        },
        "10.0.10": {
            "js/dashboard.js": "0452c596670f4dc16a5a2c8a916eabc31f21de3a",
            "js/fileupload.js": "f219113896331ae9b4d332996a471ef8866abb24",
            "js/modules/Kanban/Kanban.js": "b7c98682448f2b91040ee2ea6b4dfa618a9f0fa6"
        },
        "10.0.11": {
            "js/fileupload.js": "2e217e9910b06740b03eaa4095d6ef424ee21b59",
            "js/common.js": "46809bd10d5d61ea27a1a9d2ebe8db7d3f02fcd3",
            "js/modules/Debug/Debug.js": "6dd42dcfe1a41f0cbe6b997f47e6456a22bfb89c"
        },
        "10.0.12": {
            "js/Forms/FaIconSelector.js": "96e8f8eb01d12a39b7a0ba71f2719f70c3775093",
            "js/RichText/ContentTemplatesParameters.js": "eddaefa64bfe0b1388e6168de339cc9b75da08c2",
            "js/planning.js": "97372206ca320ded89067d4d3718715d097cc2f3"
        },
        "10.0.13": {
            "js/modules/Debug/Debug.js": "9a3863e61897031b9a57ed16e98ffd986d2ac8a4",
            "js/modules/Kanban/Kanban.js": "d4e7241c6c4d7ea752318a470d386b2c8917443f",
            "js/planning.js": "efc242378e54623df98337a433ec2952eef29f73"
        },
        "10.0.14": {
            "js/RichText/ContentTemplatesParameters.js": "eddaefa64bfe0b1388e6168de339cc9b75da08c2",
            "js/RichText/UserMention.js": "972f37b7d8a5128bc3a1b6db085ff2b27cdcba47",
            "js/planning.js": "efc242378e54623df98337a433ec2952eef29f73"
        },
        "10.0.15": {
            "js/RichText/ContentTemplatesParameters.js": "baf7496688ef4284d030f9172159eea1e1ab6c32",
            "js/RichText/UserMention.js": "2e0cb3639ed9ddcf1fb21e8631309939aa058edd",
            "js/impact.js": "f99ae7cd9de10862fefeb51b5b0ab5133e34de41"
        },
        "10.0.16": {
            "js/impact.js": "2b1d065c23a53c03d15d313bedd918de587c3bfa",
            "js/common.js": "80be4330869288ba998a945692766e677d8be696",
            "js/planning.js": "55d14c857004bb88ed0e9ae2ac0faef286d9b6c8"
        },
        "10.0.17": {
            "js/common.js": "ab2d35e2864d71ff9b16d13934f6674dca693c00",
            "js/planning.js": "b027e9ca19cbfbcf5391ac3b9fc6221f305cd3e3",
            "js/RichText/UserMention.js": "2e0cb3639ed9ddcf1fb21e8631309939aa058edd"
        },
        "10.0.18": {
            "js/clipboard.js": "dcc537e1a938ff8e0c5fe32d8dd119636d8c29c7",
            "js/planning.js": "46a0ae65680e3d092e23f5fdf9d2c96d5567137b",
            "js/RichText/UserMention.js": "4beefa891b1437453c922e98d69f21f3f6ad6a3c"
        },
        "10.0.19": {
            "js/planning.js": "36a18b30ad3948a6163c19fd6664b995d81c585d",
            "js/impact.js": "e9e01a05eebb8eef1787c196e7c3834293491815"
        },
        "10.0.20": {
            "js/impact.js": "dc352017fa305d810e8144446671066252b254da",
            "js/RichText/UserMention.js": "62760764f680a1861ef4cf6e563368937ab2e92b",
            "js/Forms/FaIconSelector.js": "ef444e6052b42d60ccff4486fe7515f44b008031",
        },
        "11.0.0": {
            "js/Forms/FaIconSelector.js": "ef111bef678aaab65ae497423dde92f32da418a2",
            "js/RichText/ContentTemplatesParameters.js": "ab7411da2c09cc59822c6538cbaeb7cc9e66c5d9",
            "js/common.js": "cb4e231b100ef3be742d73e2684857e39fd2df20",
            "js/common_ajax_controller.js": "fcf426336bd0342803b08b057075e1ab65206243",
        },
        "11.0.1": {
            "js/common.js": "aa9d208f175e4e04c5dc263680578fec2fede30b",
            "js/common_ajax_controller.js": "a12b096652c2ec433480e5de3e0681ffb559e9b7",
        }
    }

    STATIC_FILES_MAJOR_VERSION = {
        "10.0.0": {
            "js/RichText/FormTags.js": StaticFile.NOT_FOUND,
            "front/helpdesk.html": StaticFile.EXISTS
        },
        "11.0.0": {
            "front/helpdesk.html": StaticFile.NOT_FOUND,
            "js/modules/Forms/EditorController.js": StaticFile.EXISTS
        }
    }

    @classmethod
    def _check_res(cls, expected, html_result):
        return ((expected == StaticFile.NOT_FOUND
                 and html_result.status_code == HTTPStatus.NOT_FOUND)
                or
                (expected == StaticFile.EXISTS and html_result.status_code == HTTPStatus.OK)
                or
                (expected == sha1(html_result.content)))

    @classmethod
    def get_minor_from_major(cls, version):
        """
        Return the versions associated to a major version

        :return: The dict of the versions associated to a major version
        :rtype: Dict[str, Dict[str, Union[int, str]]]
        """
        major_version = version.split(".")[0]
        return {version: val for version, val in cls.STATIC_FILES_VERSION.items()
                             if version.startswith(major_version)}

    @classmethod
    def is_result_valid(cls, version, file, html_result):
        """
        Check if a result is valid given:
          - version checked
          - file path used
          - html result obtained

        :param version: The version we are testing
        :type version: str

        :param file: The file path that was requested
        :type file: str

        :param html_result: The result of the get request to the file
        :type html_result: requests.models.Response
        """
        if file in cls.STATIC_FILES_MAJOR_VERSION.get(version, {}):
            expected_result = cls.STATIC_FILES_MAJOR_VERSION[version][file]
            if not cls._check_res(expected_result, html_result):
                return False

        if file in cls.STATIC_FILES_VERSION.get(version, {}):
            expected_result = cls.STATIC_FILES_VERSION[version][file]
            if not cls._check_res(expected_result, html_result):
                return False
        return True

    @classmethod
    def get_major(cls):
        return cls.STATIC_FILES_MAJOR_VERSION

    @classmethod
    def potential_version_from_hash(cls, static_hash):
        """
        Get the potential version of the target from a given static_hash
        """
        versions = []
        for version, path_hash_combo in cls.STATIC_FILES_VERSION.items():
            if static_hash in path_hash_combo.keys():
                versions.append(version)
                continue
        return versions

    @classmethod
    def get_diff(cls, version1, version2):
        """
        Return files that differs between two versions

        :rtype: List[str]
        """
        first_hash = cls.STATIC_FILES_VERSION[version1]
        second_hash = cls.STATIC_FILES_VERSION[version2]
        diff_files = []
        for file, file_hash in first_hash.items():
            if(file in second_hash.keys() and file_hash != second_hash[file]):
                # Same file different hash
                diff_files.append(file)
        return diff_files
