"""
This module provides utilities for updating files.

Functions:
- update_helm_tpl: Update the Helm chart template files.
- update_manifest: Update the manifest file.
- update_setup_cfg: Update the setup.cfg file.
- update_setup_py: Update the setup.py file.
- _get_setup_filepath: Get the setup file path.
- _update_file: Update the file content.

"""

import re
import os

from isee.common import get_env_var, get_file_path


def update_helm_tpl():
    def update_helpers_tpl(root_path):
        hostname = get_env_var("AWS_HOSTNAME")
        repository = get_env_var("AWS_REPOSITORY")
        image_version = get_env_var("IMAGE_VERSION")
        path = get_file_path("_helpers.tpl", root_path)
        pattern = rf'({{{{- define "{repository}.image" }}}}{hostname}\/{repository}:).+({{{{- end -}}}})'
        _update_file(path, pattern, rf"\g<1>{image_version}\g<2>")

    def update_chart_config(root_path):
        chart_version = get_env_var("CHART_VERSION")
        path = get_file_path("Chart.yaml", root_path)
        _update_file(path, r"version: [\d.]+", f"version: {chart_version}")

    root_path = get_env_var("HELM_TPL_DIR")
    update_helpers_tpl(root_path)
    update_chart_config(root_path)


def update_manifest(manifest_path: str):
    repository = get_env_var("AWS_REPOSITORY")
    chart_version = get_env_var("CHART_VERSION")
    pattern = rf'("chartName":"adi\/{repository}",(\n\s*)?"chartVersion":")[\d.]+'
    _update_file(manifest_path, pattern, rf"\g<1>{chart_version}")


def update_setup_cfg(*, project_dir=None, version=None):
    path = _get_setup_filepath("setup.cfg", project_dir)
    version = version or get_env_var("VERSION")
    _update_file(path, r"version\s=\s.+", f"version = {version}")


def update_setup_py(*, project_dir=None, version=None):
    path = _get_setup_filepath("setup.py", project_dir)
    version = version or get_env_var("VERSION")
    _update_file(path, r"version='.+',", f"version='{version}',")


def _get_setup_filepath(filename, project_dir):
    project_dir = project_dir or get_env_var("GITHUB_WORKSPACE")
    return os.path.join(project_dir, filename)


def _update_file(path, pattern, replace, content_must_change=False):
    with open(path, "r+") as file:
        content = file.read()
        content_new = re.sub(pattern, replace, content, flags=re.M)
        if content_new == content and content_must_change:
            raise RuntimeError(
                f'File content unchanged. Failed to update file "{path}"!'
            )
        file.seek(0)
        file.write(content_new)
        file.truncate()
