# Copyright (C) 2018 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.
"""Helper functions for updaters."""

from collections.abc import Sequence
import os
import re
import subprocess
import sys
from pathlib import Path
from typing import List, Tuple, Type

from base_updater import Updater
import fileutils
# pylint: disable=import-error
import metadata_pb2  # type: ignore


def create_updater(metadata: metadata_pb2.MetaData, proj_path: Path,
                   updaters: List[Type[Updater]]) -> Updater:
    """Creates corresponding updater object for a project.

    Args:
      metadata: Parsed proto for METADATA file.
      proj_path: Absolute path for the project.

    Returns:
      An updater object.

    Raises:
      ValueError: Occurred when there's no updater for all urls.
    """
    for identifier in metadata.third_party.identifier:
        if identifier.type.lower() != 'homepage':
            for updater_cls in updaters:
                updater = updater_cls(proj_path, identifier, metadata.third_party.version)
                if updater.is_supported_url():
                    return updater

    raise ValueError('No supported URL.')


def replace_package(source_dir, target_dir, temp_file=None) -> None:
    """Invokes a shell script to prepare and update a project.

    Args:
      source_dir: Path to the new downloaded and extracted package.
      target_dir: The path to the project in Android source tree.
    """

    print(f'Updating {target_dir} using {source_dir}.')
    script_path = os.path.join(os.path.dirname(sys.argv[0]),
                               'update_package.sh')
    subprocess.check_call(['bash', script_path, source_dir, target_dir,
                           "" if temp_file is None else temp_file])


def run_post_update(proj_path: Path, old_project_path: Path | None = None) -> None:
    """ Runs the post_update.sh script if exists.

    Args:
      proj_path: The path to the project in Android source tree. Note that this
      project is now updated.
      old_project_path: Temp dir to where it stored the old version after
      upgrading the project.
    """
    post_update_path = os.path.join(proj_path, 'post_update.sh')
    if os.path.isfile(post_update_path):
        print(f"Running post update script {post_update_path}")
        cmd: Sequence[str | Path]
        if old_project_path:
            cmd = ['bash', post_update_path, proj_path, old_project_path]
        else:
            cmd = ['bash', post_update_path, proj_path]
        subprocess.check_call(cmd)


VERSION_SPLITTER_PATTERN: str = r'[\.\-_]'
VERSION_PATTERN: str = (r'^(?P<prefix>[^\d]*)' + r'(?P<version>\d+(' +
                        VERSION_SPLITTER_PATTERN + r'\d+)*)' +
                        r'(?P<suffix>.*)$')
TAG_PATTERN: str = r".*refs/tags/(?P<tag>[^\^]*).*"
TAG_RE: re.Pattern = re.compile(TAG_PATTERN)
VERSION_RE: re.Pattern = re.compile(VERSION_PATTERN)
VERSION_SPLITTER_RE: re.Pattern = re.compile(VERSION_SPLITTER_PATTERN)

ParsedVersion = Tuple[List[int], str, str]


def _parse_version(version: str) -> ParsedVersion:
    match = VERSION_RE.match(version)
    if match is None:
        raise ValueError('Invalid version.')
    try:
        prefix, version, suffix = match.group('prefix', 'version', 'suffix')
        versions = [int(v) for v in VERSION_SPLITTER_RE.split(version)]
        return versions, str(prefix), str(suffix)
    except IndexError:
        # pylint: disable=raise-missing-from
        raise ValueError('Invalid version.')


def _match_and_get_version(old_ver: ParsedVersion,
                           version: str) -> Tuple[bool, bool, List[int]]:
    try:
        new_ver = _parse_version(version)
    except ValueError:
        return False, False, []

    right_format = new_ver[1:] == old_ver[1:]
    right_length = len(new_ver[0]) == len(old_ver[0])

    return right_format, right_length, new_ver[0]


def get_latest_stable_release_tag(current_version: str, version_list: List[str]) -> str:
    """Gets the latest version name from a list of versions.

    The new version must have the same prefix and suffix with old version.
    If no matched version is newer, current version name will be returned.
    """
    parsed_current_ver = _parse_version(current_version)

    latest = max(
        version_list,
        key=lambda ver: _match_and_get_version(parsed_current_ver, ver),
        default=None)
    if not latest:
        raise ValueError('No matching version.')
    return latest


def parse_remote_tag(line: str) -> str:
    if (m := TAG_RE.match(line)) is not None:
        return m.group("tag")
    raise ValueError(f"Could not parse tag from {line}")


def build(proj_path: Path) -> None:
    tree = fileutils.find_tree_containing(proj_path)
    cmd = [
        str(tree / 'build/soong/soong_ui.bash'),
        "--build-mode",
        "--modules-in-a-dir",
        f"--dir={str(proj_path)}",
    ]
    print('Building...')
    subprocess.run(cmd, check=True, text=True)
