import json
import os

from enum import auto, Enum
from typing import Any, Dict, List, NamedTuple, Optional, Tuple


JSON = Dict[str, Any]


DEFAULT_MAP_FILE = "projects.json"


class DownloadType(str, Enum):
    GIT = "git"
    ZIP = "zip"
    SCRIPT = "script"


class Size(int, Enum):
    """
    Size of the project.

    Sizes do not directly correspond to the number of lines or files in the
    project.  The key factor that is important for the developers of the
    analyzer is the time it takes to analyze the project.  Here is how
    the following sizes map to times:

    TINY:  <1min
    SMALL: 1min-10min
    BIG:   10min-1h
    HUGE:  >1h

    The borders are a bit of a blur, especially because analysis time varies
    from one machine to another.  However, the relative times will stay pretty
    similar, and these groupings will still be helpful.

    UNSPECIFIED is a very special case, which is intentionally last in the list
    of possible sizes.  If the user wants to filter projects by one of the
    possible sizes, we want projects with UNSPECIFIED size to be filtered out
    for any given size.
    """
    TINY = auto()
    SMALL = auto()
    BIG = auto()
    HUGE = auto()
    UNSPECIFIED = auto()

    @staticmethod
    def from_str(raw_size: Optional[str]) -> "Size":
        """
        Construct a Size object from an optional string.

        :param raw_size: optional string representation of the desired Size
                         object.  None will produce UNSPECIFIED size.

        This method is case-insensitive, so raw sizes 'tiny', 'TINY', and
        'TiNy' will produce the same result.
        """
        if raw_size is None:
            return Size.UNSPECIFIED

        raw_size_upper = raw_size.upper()
        # The implementation is decoupled from the actual values of the enum,
        # so we can easily add or modify it without bothering about this
        # function.
        for possible_size in Size:
            if possible_size.name == raw_size_upper:
                return possible_size

        possible_sizes = [size.name.lower() for size in Size
                          # no need in showing our users this size
                          if size != Size.UNSPECIFIED]
        raise ValueError(f"Incorrect project size '{raw_size}'. "
                         f"Available sizes are {possible_sizes}")


class ProjectInfo(NamedTuple):
    """
    Information about a project to analyze.
    """
    name: str
    mode: int
    source: DownloadType = DownloadType.SCRIPT
    origin: str = ""
    commit: str = ""
    enabled: bool = True
    size: Size = Size.UNSPECIFIED

    def with_fields(self, **kwargs) -> "ProjectInfo":
        """
        Create a copy of this project info with customized fields.
        NamedTuple is immutable and this is a way to create modified copies.

          info.enabled = True
          info.mode = 1

        can be done as follows:

          modified = info.with_fields(enbled=True, mode=1)
        """
        return ProjectInfo(**{**self._asdict(), **kwargs})


class ProjectMap:
    """
    Project map stores info about all the "registered" projects.
    """
    def __init__(self, path: Optional[str] = None, should_exist: bool = True):
        """
        :param path: optional path to a project JSON file, when None defaults
                     to DEFAULT_MAP_FILE.
        :param should_exist: flag to tell if it's an exceptional situation when
                             the project file doesn't exist, creates an empty
                             project list instead if we are not expecting it to
                             exist.
        """
        if path is None:
            path = os.path.join(os.path.abspath(os.curdir), DEFAULT_MAP_FILE)

        if not os.path.exists(path):
            if should_exist:
                raise ValueError(
                    f"Cannot find the project map file {path}"
                    f"\nRunning script for the wrong directory?\n")
            else:
                self._create_empty(path)

        self.path = path
        self._load_projects()

    def save(self):
        """
        Save project map back to its original file.
        """
        self._save(self.projects, self.path)

    def _load_projects(self):
        with open(self.path) as raw_data:
            raw_projects = json.load(raw_data)

            if not isinstance(raw_projects, list):
                raise ValueError(
                    "Project map should be a list of JSON objects")

            self.projects = self._parse(raw_projects)

    @staticmethod
    def _parse(raw_projects: List[JSON]) -> List[ProjectInfo]:
        return [ProjectMap._parse_project(raw_project)
                for raw_project in raw_projects]

    @staticmethod
    def _parse_project(raw_project: JSON) -> ProjectInfo:
        try:
            name: str = raw_project["name"]
            build_mode: int = raw_project["mode"]
            enabled: bool = raw_project.get("enabled", True)
            source: DownloadType = raw_project.get("source", "zip")
            size = Size.from_str(raw_project.get("size", None))

            if source == DownloadType.GIT:
                origin, commit = ProjectMap._get_git_params(raw_project)
            else:
                origin, commit = "", ""

            return ProjectInfo(name, build_mode, source, origin, commit,
                               enabled, size)

        except KeyError as e:
            raise ValueError(
                f"Project info is required to have a '{e.args[0]}' field")

    @staticmethod
    def _get_git_params(raw_project: JSON) -> Tuple[str, str]:
        try:
            return raw_project["origin"], raw_project["commit"]
        except KeyError as e:
            raise ValueError(
                f"Profect info is required to have a '{e.args[0]}' field "
                f"if it has a 'git' source")

    @staticmethod
    def _create_empty(path: str):
        ProjectMap._save([], path)

    @staticmethod
    def _save(projects: List[ProjectInfo], path: str):
        with open(path, "w") as output:
            json.dump(ProjectMap._convert_infos_to_dicts(projects),
                      output, indent=2)

    @staticmethod
    def _convert_infos_to_dicts(projects: List[ProjectInfo]) -> List[JSON]:
        return [ProjectMap._convert_info_to_dict(project)
                for project in projects]

    @staticmethod
    def _convert_info_to_dict(project: ProjectInfo) -> JSON:
        whole_dict = project._asdict()
        defaults = project._field_defaults

        # there is no need in serializing fields with default values
        for field, default_value in defaults.items():
            if whole_dict[field] == default_value:
                del whole_dict[field]

        return whole_dict
