import re
import subprocess
from pathlib import Path

from dbt_platform_helper.constants import DEFAULT_TERRAFORM_PLATFORM_MODULES_VERSION
from dbt_platform_helper.providers.platform_helper_versioning import (
    PlatformHelperVersioning,
)
from dbt_platform_helper.providers.semantic_version import PlatformHelperVersionStatus
from dbt_platform_helper.providers.semantic_version import SemanticVersion
from dbt_platform_helper.providers.semantic_version import VersionStatus
from dbt_platform_helper.providers.validation import ValidationException
from dbt_platform_helper.providers.version import GithubVersionProvider
from dbt_platform_helper.providers.yaml_file import YamlFileProvider


# TODO to be removed after config tests are updated - temporary wrapper mid-refactor
def get_platform_helper_version_status(
    include_project_versions=True,
    yaml_provider=YamlFileProvider,
) -> PlatformHelperVersionStatus:
    return PlatformHelperVersioning(file_provider=yaml_provider).get_status(
        include_project_versions=include_project_versions
    )


def get_required_terraform_platform_modules_version(
    cli_terraform_platform_modules_version, platform_config_terraform_modules_default_version
):
    version_preference_order = [
        cli_terraform_platform_modules_version,
        platform_config_terraform_modules_default_version,
        DEFAULT_TERRAFORM_PLATFORM_MODULES_VERSION,
    ]
    return [version for version in version_preference_order if version][0]


##################################################################################
# Only used in Config domain
# TODO Relocate along with tests when we refactor config command in DBTP-1538
##################################################################################


# Getting version from the "Generated by" comment in a file that was generated from a template
# TODO where does this belong?  It sort of belongs to our platform-helper templating
def get_template_generated_with_version(template_file_path: str) -> SemanticVersion:
    try:
        template_contents = Path(template_file_path).read_text()
        template_version = re.match(
            r"# Generated by platform-helper ([v.\-0-9]+)", template_contents
        ).group(1)
        return SemanticVersion.from_string(template_version)
    except (IndexError, AttributeError):
        raise ValidationException(f"Template {template_file_path} has no version information")


def validate_template_version(app_version: SemanticVersion, template_file_path: str):
    app_version.validate_compatibility_with(get_template_generated_with_version(template_file_path))


# Local version and latest release of tool.
# Used only in config command.
# TODO Move to config domain
def get_copilot_versions() -> VersionStatus:
    copilot_version = None

    try:
        response = subprocess.run("copilot --version", capture_output=True, shell=True)
        [copilot_version] = re.findall(r"[0-9.]+", response.stdout.decode("utf8"))
    except ValueError:
        pass

    return VersionStatus(
        SemanticVersion.from_string(copilot_version),
        GithubVersionProvider.get_latest_version("aws/copilot-cli"),
    )


# Local version and latest release of tool.
# Used only in config command.
# TODO Move to config domain
def get_aws_versions() -> VersionStatus:
    aws_version = None
    try:
        response = subprocess.run("aws --version", capture_output=True, shell=True)
        matched = re.match(r"aws-cli/([0-9.]+)", response.stdout.decode("utf8"))
        aws_version = SemanticVersion.from_string(matched.group(1))
    except ValueError:
        pass

    return VersionStatus(aws_version, GithubVersionProvider.get_latest_version("aws/aws-cli", True))
