# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import contextlib
import datetime
import errno
import http.client
import json
import os
import re
import ssl
import subprocess
import sys
from typing import Union
import urllib.error
import urllib.request

from error import GitError
from error import UploadError
from git_command import GitCommand
from git_refs import R_CHANGES
from git_refs import R_HEADS
from git_refs import R_TAGS
import platform_utils
from repo_trace import Trace


# Prefix that is prepended to all the keys of SyncAnalysisState's data
# that is saved in the config.
SYNC_STATE_PREFIX = "repo.syncstate."

ID_RE = re.compile(r"^[0-9a-f]{40}$")

REVIEW_CACHE = dict()


def IsChange(rev):
    return rev.startswith(R_CHANGES)


def IsId(rev):
    return ID_RE.match(rev)


def IsTag(rev):
    return rev.startswith(R_TAGS)


def IsImmutable(rev):
    return IsChange(rev) or IsId(rev) or IsTag(rev)


def _key(name):
    parts = name.split(".")
    if len(parts) < 2:
        return name.lower()
    parts[0] = parts[0].lower()
    parts[-1] = parts[-1].lower()
    return ".".join(parts)


class GitConfig:
    _ForUser = None

    _ForSystem = None
    _SYSTEM_CONFIG = "/etc/gitconfig"

    @classmethod
    def ForSystem(cls):
        if cls._ForSystem is None:
            cls._ForSystem = cls(configfile=cls._SYSTEM_CONFIG)
        return cls._ForSystem

    @classmethod
    def ForUser(cls):
        if cls._ForUser is None:
            cls._ForUser = cls(configfile=cls._getUserConfig())
        return cls._ForUser

    @staticmethod
    def _getUserConfig():
        """Get the user-specific config file.

        Prefers the XDG config location if available, with fallback to
        ~/.gitconfig

        This matches git behavior:
        https://git-scm.com/docs/git-config#FILES
        """
        xdg_config_home = os.getenv(
            "XDG_CONFIG_HOME", os.path.expanduser("~/.config")
        )
        xdg_config_file = os.path.join(xdg_config_home, "git", "config")
        if os.path.exists(xdg_config_file):
            return xdg_config_file
        return os.path.expanduser("~/.gitconfig")

    @classmethod
    def ForRepository(cls, gitdir, defaults=None):
        return cls(configfile=os.path.join(gitdir, "config"), defaults=defaults)

    def __init__(self, configfile, defaults=None, jsonFile=None):
        self.file = configfile
        self.defaults = defaults
        self._cache_dict = None
        self._section_dict = None
        self._remotes = {}
        self._branches = {}

        self._json = jsonFile
        if self._json is None:
            self._json = os.path.join(
                os.path.dirname(self.file),
                ".repo_" + os.path.basename(self.file) + ".json",
            )

    def ClearCache(self):
        """Clear the in-memory cache of config."""
        self._cache_dict = None

    def Has(self, name, include_defaults=True):
        """Return true if this configuration file has the key."""
        if _key(name) in self._cache:
            return True
        if include_defaults and self.defaults:
            return self.defaults.Has(name, include_defaults=True)
        return False

    def GetInt(self, name: str) -> Union[int, None]:
        """Returns an integer from the configuration file.

        This follows the git config syntax.

        Args:
            name: The key to lookup.

        Returns:
            None if the value was not defined, or is not an int.
            Otherwise, the number itself.
        """
        v = self.GetString(name)
        if v is None:
            return None
        v = v.strip()

        mult = 1
        if v.endswith("k"):
            v = v[:-1]
            mult = 1024
        elif v.endswith("m"):
            v = v[:-1]
            mult = 1024 * 1024
        elif v.endswith("g"):
            v = v[:-1]
            mult = 1024 * 1024 * 1024

        base = 10
        if v.startswith("0x"):
            base = 16

        try:
            return int(v, base=base) * mult
        except ValueError:
            print(
                f"warning: expected {name} to represent an integer, got {v} "
                "instead",
                file=sys.stderr,
            )
            return None

    def DumpConfigDict(self):
        """Returns the current configuration dict.

        Configuration data is information only (e.g. logging) and
        should not be considered a stable data-source.

        Returns:
            dict of {<key>, <value>} for git configuration cache.
            <value> are strings converted by GetString.
        """
        config_dict = {}
        for key in self._cache:
            config_dict[key] = self.GetString(key)
        return config_dict

    def GetBoolean(self, name: str) -> Union[bool, None]:
        """Returns a boolean from the configuration file.

        Returns:
            None: The value was not defined, or is not a boolean.
            True: The value was set to true or yes.
            False: The value was set to false or no.
        """
        v = self.GetString(name)
        if v is None:
            return None
        v = v.lower()
        if v in ("true", "yes"):
            return True
        if v in ("false", "no"):
            return False
        print(
            f"warning: expected {name} to represent a boolean, got {v} instead",
            file=sys.stderr,
        )
        return None

    def SetBoolean(self, name, value):
        """Set the truthy value for a key."""
        if value is not None:
            value = "true" if value else "false"
        self.SetString(name, value)

    def GetString(self, name: str, all_keys: bool = False) -> Union[str, None]:
        """Get the first value for a key, or None if it is not defined.

        This configuration file is used first, if the key is not
        defined or all_keys = True then the defaults are also searched.
        """
        try:
            v = self._cache[_key(name)]
        except KeyError:
            if self.defaults:
                return self.defaults.GetString(name, all_keys=all_keys)
            v = []

        if not all_keys:
            if v:
                return v[0]
            return None

        r = []
        r.extend(v)
        if self.defaults:
            r.extend(self.defaults.GetString(name, all_keys=True))
        return r

    def SetString(self, name, value):
        """Set the value(s) for a key.
        Only this configuration file is modified.

        The supplied value should be either a string, or a list of strings (to
        store multiple values), or None (to delete the key).
        """
        key = _key(name)

        try:
            old = self._cache[key]
        except KeyError:
            old = []

        if value is None:
            if old:
                del self._cache[key]
                self._do("--unset-all", name)

        elif isinstance(value, list):
            if len(value) == 0:
                self.SetString(name, None)

            elif len(value) == 1:
                self.SetString(name, value[0])

            elif old != value:
                self._cache[key] = list(value)
                self._do("--replace-all", name, value[0])
                for i in range(1, len(value)):
                    self._do("--add", name, value[i])

        elif len(old) != 1 or old[0] != value:
            self._cache[key] = [value]
            self._do("--replace-all", name, value)

    def GetRemote(self, name):
        """Get the remote.$name.* configuration values as an object."""
        try:
            r = self._remotes[name]
        except KeyError:
            r = Remote(self, name)
            self._remotes[r.name] = r
        return r

    def GetBranch(self, name):
        """Get the branch.$name.* configuration values as an object."""
        try:
            b = self._branches[name]
        except KeyError:
            b = Branch(self, name)
            self._branches[b.name] = b
        return b

    def GetSyncAnalysisStateData(self):
        """Returns data to be logged for the analysis of sync performance."""
        return {
            k: v
            for k, v in self.DumpConfigDict().items()
            if k.startswith(SYNC_STATE_PREFIX)
        }

    def UpdateSyncAnalysisState(self, options, superproject_logging_data):
        """Update Config's SYNC_STATE_PREFIX* data with the latest sync data.

        Args:
            options: Options passed to sync returned from optparse. See
                _Options().
            superproject_logging_data: A dictionary of superproject data that is
                to be logged.

        Returns:
            SyncAnalysisState object.
        """
        return SyncAnalysisState(self, options, superproject_logging_data)

    def GetSubSections(self, section):
        """List all subsection names matching $section.*.*"""
        return self._sections.get(section, set())

    def HasSection(self, section, subsection=""):
        """Does at least one key in section.subsection exist?"""
        try:
            return subsection in self._sections[section]
        except KeyError:
            return False

    def UrlInsteadOf(self, url):
        """Resolve any url.*.insteadof references."""
        for new_url in self.GetSubSections("url"):
            for old_url in self.GetString("url.%s.insteadof" % new_url, True):
                if old_url is not None and url.startswith(old_url):
                    return new_url + url[len(old_url) :]
        return url

    @property
    def _sections(self):
        d = self._section_dict
        if d is None:
            d = {}
            for name in self._cache.keys():
                p = name.split(".")
                if 2 == len(p):
                    section = p[0]
                    subsect = ""
                else:
                    section = p[0]
                    subsect = ".".join(p[1:-1])
                if section not in d:
                    d[section] = set()
                d[section].add(subsect)
                self._section_dict = d
        return d

    @property
    def _cache(self):
        if self._cache_dict is None:
            self._cache_dict = self._Read()
        return self._cache_dict

    def _Read(self):
        d = self._ReadJson()
        if d is None:
            d = self._ReadGit()
            self._SaveJson(d)
        return d

    def _ReadJson(self):
        try:
            if os.path.getmtime(self._json) <= os.path.getmtime(self.file):
                platform_utils.remove(self._json)
                return None
        except OSError:
            return None
        try:
            with Trace(": parsing %s", self.file):
                with open(self._json) as fd:
                    return json.load(fd)
        except (OSError, ValueError):
            platform_utils.remove(self._json, missing_ok=True)
            return None

    def _SaveJson(self, cache):
        try:
            with open(self._json, "w") as fd:
                json.dump(cache, fd, indent=2)
        except (OSError, TypeError):
            platform_utils.remove(self._json, missing_ok=True)

    def _ReadGit(self):
        """
        Read configuration data from git.

        This internal method populates the GitConfig cache.

        """
        c = {}
        if not os.path.exists(self.file):
            return c

        d = self._do("--null", "--list")
        for line in d.rstrip("\0").split("\0"):
            if "\n" in line:
                key, val = line.split("\n", 1)
            else:
                key = line
                val = None

            if key in c:
                c[key].append(val)
            else:
                c[key] = [val]

        return c

    def _do(self, *args):
        if self.file == self._SYSTEM_CONFIG:
            command = ["config", "--system", "--includes"]
        else:
            command = ["config", "--file", self.file, "--includes"]
        command.extend(args)

        p = GitCommand(None, command, capture_stdout=True, capture_stderr=True)
        if p.Wait() == 0:
            return p.stdout
        else:
            raise GitError(f"git config {str(args)}: {p.stderr}")


class RepoConfig(GitConfig):
    """User settings for repo itself."""

    @staticmethod
    def _getUserConfig():
        repo_config_dir = os.getenv("REPO_CONFIG_DIR", os.path.expanduser("~"))
        return os.path.join(repo_config_dir, ".repoconfig/config")


class RefSpec:
    """A Git refspec line, split into its components:

    forced:  True if the line starts with '+'
    src:     Left side of the line
    dst:     Right side of the line
    """

    @classmethod
    def FromString(cls, rs):
        lhs, rhs = rs.split(":", 2)
        if lhs.startswith("+"):
            lhs = lhs[1:]
            forced = True
        else:
            forced = False
        return cls(forced, lhs, rhs)

    def __init__(self, forced, lhs, rhs):
        self.forced = forced
        self.src = lhs
        self.dst = rhs

    def SourceMatches(self, rev):
        if self.src:
            if rev == self.src:
                return True
            if self.src.endswith("/*") and rev.startswith(self.src[:-1]):
                return True
        return False

    def DestMatches(self, ref):
        if self.dst:
            if ref == self.dst:
                return True
            if self.dst.endswith("/*") and ref.startswith(self.dst[:-1]):
                return True
        return False

    def MapSource(self, rev):
        if self.src.endswith("/*"):
            return self.dst[:-1] + rev[len(self.src) - 1 :]
        return self.dst

    def __str__(self):
        s = ""
        if self.forced:
            s += "+"
        if self.src:
            s += self.src
        if self.dst:
            s += ":"
            s += self.dst
        return s


URI_ALL = re.compile(r"^([a-z][a-z+-]*)://([^@/]*@?[^/]*)/")


def GetSchemeFromUrl(url):
    m = URI_ALL.match(url)
    if m:
        return m.group(1)
    return None


@contextlib.contextmanager
def GetUrlCookieFile(url, quiet):
    if url.startswith("persistent-"):
        try:
            p = subprocess.Popen(
                ["git-remote-persistent-https", "-print_config", url],
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            try:
                cookieprefix = "http.cookiefile="
                proxyprefix = "http.proxy="
                cookiefile = None
                proxy = None
                for line in p.stdout:
                    line = line.strip().decode("utf-8")
                    if line.startswith(cookieprefix):
                        cookiefile = os.path.expanduser(
                            line[len(cookieprefix) :]
                        )
                    if line.startswith(proxyprefix):
                        proxy = line[len(proxyprefix) :]
                # Leave subprocess open, as cookie file may be transient.
                if cookiefile or proxy:
                    yield cookiefile, proxy
                    return
            finally:
                p.stdin.close()
                if p.wait():
                    err_msg = p.stderr.read().decode("utf-8")
                    if " -print_config" in err_msg:
                        pass  # Persistent proxy doesn't support -print_config.
                    elif not quiet:
                        print(err_msg, file=sys.stderr)
        except OSError as e:
            if e.errno == errno.ENOENT:
                pass  # No persistent proxy.
            raise
    cookiefile = GitConfig.ForUser().GetString("http.cookiefile")
    if cookiefile:
        cookiefile = os.path.expanduser(cookiefile)
    yield cookiefile, None


class Remote:
    """Configuration options related to a remote."""

    def __init__(self, config, name):
        self._config = config
        self.name = name
        self.url = self._Get("url")
        self.pushUrl = self._Get("pushurl")
        self.review = self._Get("review")
        self.projectname = self._Get("projectname")
        self.fetch = list(
            map(RefSpec.FromString, self._Get("fetch", all_keys=True))
        )
        self._review_url = None

    def _InsteadOf(self):
        globCfg = GitConfig.ForUser()
        urlList = globCfg.GetSubSections("url")
        longest = ""
        longestUrl = ""

        for url in urlList:
            key = "url." + url + ".insteadOf"
            insteadOfList = globCfg.GetString(key, all_keys=True)

            for insteadOf in insteadOfList:
                if self.url.startswith(insteadOf) and len(insteadOf) > len(
                    longest
                ):
                    longest = insteadOf
                    longestUrl = url

        if len(longest) == 0:
            return self.url

        return self.url.replace(longest, longestUrl, 1)

    def PreConnectFetch(self, ssh_proxy):
        """Run any setup for this remote before we connect to it.

        In practice, if the remote is using SSH, we'll attempt to create a new
        SSH master session to it for reuse across projects.

        Args:
            ssh_proxy: The SSH settings for managing master sessions.

        Returns:
            Whether the preconnect phase for this remote was successful.
        """
        if not ssh_proxy:
            return True

        connectionUrl = self._InsteadOf()
        return ssh_proxy.preconnect(connectionUrl)

    def ReviewUrl(self, userEmail, validate_certs):
        if self._review_url is None:
            if self.review is None:
                return None

            u = self.review
            if u.startswith("persistent-"):
                u = u[len("persistent-") :]
            if u.split(":")[0] not in ("http", "https", "sso", "ssh"):
                u = "http://%s" % u
            if u.endswith("/Gerrit"):
                u = u[: len(u) - len("/Gerrit")]
            if u.endswith("/ssh_info"):
                u = u[: len(u) - len("/ssh_info")]
            if not u.endswith("/"):
                u += "/"
            http_url = u

            if u in REVIEW_CACHE:
                self._review_url = REVIEW_CACHE[u]
            elif "REPO_HOST_PORT_INFO" in os.environ:
                host, port = os.environ["REPO_HOST_PORT_INFO"].split()
                self._review_url = self._SshReviewUrl(userEmail, host, port)
                REVIEW_CACHE[u] = self._review_url
            elif u.startswith("sso:") or u.startswith("ssh:"):
                self._review_url = u  # Assume it's right
                REVIEW_CACHE[u] = self._review_url
            elif "REPO_IGNORE_SSH_INFO" in os.environ:
                self._review_url = http_url
                REVIEW_CACHE[u] = self._review_url
            else:
                try:
                    info_url = u + "ssh_info"
                    if not validate_certs:
                        context = ssl._create_unverified_context()
                        info = urllib.request.urlopen(
                            info_url, context=context
                        ).read()
                    else:
                        info = urllib.request.urlopen(info_url).read()
                    if info == b"NOT_AVAILABLE" or b"<" in info:
                        # If `info` contains '<', we assume the server gave us
                        # some sort of HTML response back, like maybe a login
                        # page.
                        #
                        # Assume HTTP if SSH is not enabled or ssh_info doesn't
                        # look right.
                        self._review_url = http_url
                    else:
                        info = info.decode("utf-8")
                        host, port = info.split()
                        self._review_url = self._SshReviewUrl(
                            userEmail, host, port
                        )
                except urllib.error.HTTPError as e:
                    raise UploadError(f"{self.review}: {str(e)}")
                except urllib.error.URLError as e:
                    raise UploadError(f"{self.review}: {str(e)}")
                except http.client.HTTPException as e:
                    raise UploadError(f"{self.review}: {e.__class__.__name__}")

                REVIEW_CACHE[u] = self._review_url
        return self._review_url + self.projectname

    def _SshReviewUrl(self, userEmail, host, port):
        username = self._config.GetString("review.%s.username" % self.review)
        if username is None:
            username = userEmail.split("@")[0]
        return f"ssh://{username}@{host}:{port}/"

    def ToLocal(self, rev):
        """Convert a remote revision string to something we have locally."""
        if self.name == "." or IsId(rev):
            return rev

        if not rev.startswith("refs/"):
            rev = R_HEADS + rev

        for spec in self.fetch:
            if spec.SourceMatches(rev):
                return spec.MapSource(rev)

        if not rev.startswith(R_HEADS):
            return rev

        raise GitError(
            "%s: remote %s does not have %s"
            % (self.projectname, self.name, rev)
        )

    def WritesTo(self, ref):
        """True if the remote stores to the tracking ref."""
        for spec in self.fetch:
            if spec.DestMatches(ref):
                return True
        return False

    def ResetFetch(self, mirror=False):
        """Set the fetch refspec to its default value."""
        if mirror:
            dst = "refs/heads/*"
        else:
            dst = "refs/remotes/%s/*" % self.name
        self.fetch = [RefSpec(True, "refs/heads/*", dst)]

    def Save(self):
        """Save this remote to the configuration."""
        self._Set("url", self.url)
        if self.pushUrl is not None:
            self._Set("pushurl", self.pushUrl + "/" + self.projectname)
        else:
            self._Set("pushurl", self.pushUrl)
        self._Set("review", self.review)
        self._Set("projectname", self.projectname)
        self._Set("fetch", list(map(str, self.fetch)))

    def _Set(self, key, value):
        key = f"remote.{self.name}.{key}"
        return self._config.SetString(key, value)

    def _Get(self, key, all_keys=False):
        key = f"remote.{self.name}.{key}"
        return self._config.GetString(key, all_keys=all_keys)


class Branch:
    """Configuration options related to a single branch."""

    def __init__(self, config, name):
        self._config = config
        self.name = name
        self.merge = self._Get("merge")

        r = self._Get("remote")
        if r:
            self.remote = self._config.GetRemote(r)
        else:
            self.remote = None

    @property
    def LocalMerge(self):
        """Convert the merge spec to a local name."""
        if self.remote and self.merge:
            return self.remote.ToLocal(self.merge)
        return None

    def Save(self):
        """Save this branch back into the configuration."""
        if self._config.HasSection("branch", self.name):
            if self.remote:
                self._Set("remote", self.remote.name)
            else:
                self._Set("remote", None)
            self._Set("merge", self.merge)

        else:
            with open(self._config.file, "a") as fd:
                fd.write('[branch "%s"]\n' % self.name)
                if self.remote:
                    fd.write("\tremote = %s\n" % self.remote.name)
                if self.merge:
                    fd.write("\tmerge = %s\n" % self.merge)

    def _Set(self, key, value):
        key = f"branch.{self.name}.{key}"
        return self._config.SetString(key, value)

    def _Get(self, key, all_keys=False):
        key = f"branch.{self.name}.{key}"
        return self._config.GetString(key, all_keys=all_keys)


class SyncAnalysisState:
    """Configuration options related to logging of sync state for analysis.

    This object is versioned.
    """

    def __init__(self, config, options, superproject_logging_data):
        """Initializes SyncAnalysisState.

        Saves the following data into the |config| object.
        - sys.argv, options, superproject's logging data.
        - repo.*, branch.* and remote.* parameters from config object.
        - Current time as synctime.
        - Version number of the object.

        All the keys saved by this object are prepended with SYNC_STATE_PREFIX.

        Args:
            config: GitConfig object to store all options.
            options: Options passed to sync returned from optparse. See
                _Options().
            superproject_logging_data: A dictionary of superproject data that is
                to be logged.
        """
        self._config = config
        now = datetime.datetime.now(datetime.timezone.utc)
        self._Set("main.synctime", now.isoformat(timespec="microseconds"))
        self._Set("main.version", "1")
        self._Set("sys.argv", sys.argv)
        for key, value in superproject_logging_data.items():
            self._Set(f"superproject.{key}", value)
        for key, value in options.__dict__.items():
            self._Set(f"options.{key}", value)
        config_items = config.DumpConfigDict().items()
        EXTRACT_NAMESPACES = {"repo", "branch", "remote"}
        self._SetDictionary(
            {
                k: v
                for k, v in config_items
                if not k.startswith(SYNC_STATE_PREFIX)
                and k.split(".", 1)[0] in EXTRACT_NAMESPACES
            }
        )

    def _SetDictionary(self, data):
        """Save all key/value pairs of |data| dictionary.

        Args:
            data: A dictionary whose key/value are to be saved.
        """
        for key, value in data.items():
            self._Set(key, value)

    def _Set(self, key, value):
        """Set the |value| for a |key| in the |_config| member.

        |key| is prepended with the value of SYNC_STATE_PREFIX constant.

        Args:
            key: Name of the key.
            value: |value| could be of any type. If it is 'bool', it will be
                saved as a Boolean and for all other types, it will be saved as
                a String.
        """
        if value is None:
            return
        sync_key = f"{SYNC_STATE_PREFIX}{key}"
        sync_key = sync_key.replace("_", "")
        if isinstance(value, str):
            self._config.SetString(sync_key, value)
        elif isinstance(value, bool):
            self._config.SetBoolean(sync_key, value)
        else:
            self._config.SetString(sync_key, str(value))
