#!/usr/bin/python3
"""
Driver for dh-fortran d/rules targets

Copyright (C) 2025 Alastair McKinstry <mckinstry@debian.org>
Released under the GPL-3 GNU Public License.
"""

import os
import subprocess
import sys
from os.path import exists
from functools import wraps
import dhfortran.cli as cli
import dhfortran.compilers as cmplrs


def _set_env(flavor):
    """Set Fortran env"""
    env = (
        subprocess.check_output(["dh_fortran", "get_env", "--fc", flavor])
        .strip()
        .decode("utf-8")
    )
    for line in env.split('\n'):
        key, val = line[: line.find("=")], line[line.find("=") + 1 :]
        os.environ[key] = val


def _doit(args):
    if "DH_VERBOSE" in os.environ:
        args += ["--verbose"]
    cli.verbose_print(args)
    subprocess.run(args, stdout=sys.stdout, stderr=sys.stderr)


def foreach_compiler(fail_on_error_on_default=True):

    def outer(f):
        @wraps(f)
        def inner(*args, **kwargs):
            try:
                fc_def = cmplrs.get_fc_default()
                _set_env(fc_def)
                cli.verbose_print(
                    f"Calling dh_fortran {f.__name__} with {fc_def} {args} {kwargs}"
                )  # Pre-function execution
                f(flavor=fc_def, *args, **kwargs)
            except Exception:
                if fail_on_error_on_default:
                    raise
            for flavor in cmplrs.get_fc_optional():
                try:
                    _set_env(flavor)
                    cli.verbose_print(
                        f"Calling dh_fortran {f.__name__} with {flavor} {args} {kwargs}"
                    )  # Pre-function execution
                    f(flavor)
                except Exception as ex:
                    cli.verbose_print(f"{f.__name__}: ignoring error {ex}")

        return inner

    return outer


@foreach_compiler(fail_on_error_on_default=False)
def clean(flavor: str = None):
    """Do Fortran-specific operations on d/rules clean target"""
    if exists("fpm.toml"):
        _doit(["fpm", "clean", "--all"])
    # _doit(["rm", "-rf", "debian/tmp-*", "debian/build-*"])


@foreach_compiler()
def install(flavor: str = None):
    """Do Fortran-specific operations on d/rules install target"""
    if flavor is None:
        flavor, _ = cmplrs.get_fc_flavor_arch()
    if exists("fpm.toml"):
        # TODO. paramterise tmpdir debian/tmp ?
        _doit(["fpm", "install", f"--prefix=debian/tmp-{flavor}/usr"])
        _doit(["dh_fortran_mod", f"--tmpdir=debian/tmp-{flavor}"])
        _doit(["dh_fortran_lib", f"--tmpdir=debian/tmp-{flavor}"])
        _doit(["dh_fortran_pkgconf", f"--tmpdir=debian/tmp-{flavor}"])
        _doit(["dh_fortran_cmake", f"--tmpdir=debian/tmp-{flavor}"])

@foreach_compiler()
def configure(flavor: str = None):
    """Do Fortran-specific operations on d/rules configure target"""
    pass

@foreach_compiler()
def build(flavor: str = None):
    """Do Fortran-specific operations on d/rules build target"""
    if exists("fpm.toml"):
        _doit(["fpm", "build"])
        # TODO: Call fpm build as relevant


@foreach_compiler()
def test(flavor: str = None):
    """Do Fortran-specific operations on d/rules test target"""
    if exists("fpm.toml"):
        _doit(["fpm", "test"])


if __name__ == "__main__":
    import pytest

    pytest.main(["tests/targets.py"])
