#!/usr/bin/python3
"""
Interceptor for dh-fortran targets

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

import sys
from os.path import basename, islink
from functools import wraps
import dhfortran.cli as cli
import dhfortran.compilers as cmplrs
import dhfortran.targets as tgt
import click


def foreach_compiler(fail_on_error_on_default=True):
    """ Wrapper. Execute the function on all compilers """
    def outer(f):
        @wraps(f)
        def inner(*args, **kwargs):
            cmd  = basename(sys.argv[0])
            try:
                for flavor in cmplrs.get_fc_required():
                    print(f"   {cmd} ( {flavor} env)")
                    f(flavor, cmd, *args, **kwargs)
            except Exception:
                if fail_on_error_on_default:
                    raise
            for flavor in cmplrs.get_fc_optional():
                 try:
                     print(f"   {cmd} ( {flavor} env)")
                     f(flavor,cmd, *args, **kwargs)
                 except Exception as ex:
                     cli.verbose_print(f"{cmd}: ignoring error '{ex}'"
                                       "(optional compiler)")
        return inner
    return outer




@foreach_compiler()
def dh_auto_with_flavor_env(flavor: str,cmd: str, *args, **kwargs):
    tgt.set_env(flavor)
    # Not sure the following happen
    if (" ".join(sys.argv[1:])).find('-O--builddirectory') != -1:
        cmdlist = [ f"/usr/bin/{cmd}" ] + sys.argv[1:]
    else:
        builddir = f"-O--builddirectory={kwargs['builddir']}-{flavor}"
        # TODO: calling this too early breaks things; drop tmpdir ?
        # Set only in install case ?
        # tmpdir = f"--tmpdir={kwargs['tmpdir']}-{flavor}"
        cmdlist  = [ f"/usr/bin/{cmd}", builddir] + sys.argv[1:]  
    tgt.doit(cmdlist)
    

def noop(*args, **kwargs):
    """ Helper. For now, just redirect back to /usr/bin/dh_auto_* """
    cmd  = basename(sys.argv[0])
    cmdlist  = [ f"/usr/bin/{cmd}" ] + sys.argv[1:]
    tgt.doit(cmdlist)

@click.command(
    context_settings=dict(
        ignore_unknown_options=True,
    )
)
@click.argument('args', nargs=-1, type=click.UNPROCESSED)
@cli.debhelper_common_args
def dh_fortran_clean(*args,**kwargs):
    """ Hijack and monkey-patch dh_auto_clean calls so we can set environment """
    if kwargs['buildsystem'] == 'fortran':
        tgt.doit(["fpm", "clean", "--all"],verbose=True)
    if kwargs['builddir'] is not None and islink(kwargs['builddir']):
        tgt.doit(['rm','-f',kwargs['builddir']])
    tgt.dh_fortran_clean(**kwargs)


@click.command(
    context_settings=dict( ignore_unknown_options=True,)
    )
@click.argument('args', nargs=-1, type=click.UNPROCESSED)
@cli.debhelper_common_args
def dh_auto_configure(*args, **kwargs):
    """ Hijack and monkey-patch dh_auto_configure calls so we can set environment """
    if kwargs['buildsystem'] == 'fortran':
        tgt.dh_fortran_configure(**kwargs)
    else:
        if cmplrs.is_multifortran_build():
            d = cmplrs.get_fc_default()
            if kwargs['builddir'] == 'debian/build':
                # Avoid incorrect symlink
                tgt.doit(['ln','-s',f"build-{d}","debian/build"])
            else:
                tgt.doit(['ln','-s',
                          f"{kwargs['builddir']}-{d}",
                          f"{kwargs['builddir']}"])
            dh_auto_with_flavor_env(*args, **kwargs)
        else:
            noop(*args, **kwargs)
            

@cli.debhelper_common_args
@click.argument('args', nargs=-1, type=click.UNPROCESSED)
def dh_auto_build(*args,**kwargs):
    """ Hijack and monkey-patch dh_auto_build calls so we can set environment """
    if kwargs['buildsystem'] == 'fortran':
        tgt.dh_fortran_build(**kwargs)
    else:
        if cmplrs.is_multifortran_build():
            dh_auto_with_flavor_env(*args, **kwargs)
        else:
            noop(*args, **kwargs)

@click.command(
    context_settings=dict(
        ignore_unknown_options=True,
    )
)
@cli.debhelper_common_args
@click.argument('args', nargs=-1, type=click.UNPROCESSED)
def dh_auto_install(*args,**kwargs):
    """ Hijack and monkey-patch dh_auto_install calls so we can set environment """ 
    match kwargs['buildsystem']:
        case 'fortran':
            tgt.dh_fortran_install(**kwargs)
        case 'cmake+makefile' | 'ecbuild+makefile':
            if cmplrs.is_multifortran_build():
                tgt.dh_install_on_cmake_makefile(**kwargs)
            noop(*args, **kwargs)
        case _:
            if cmplrs.is_multifortran_build():
                cli.verbose_print(f"Can't handle buildsystem {kwargs['buildsystem']};"
                                  "reverting to default behaviour")
            noop(*args, **kwargs)


@click.command(
    context_settings=dict(
        ignore_unknown_options=True,
    )
)
@click.argument('args', nargs=-1, type=click.UNPROCESSED)
@cli.debhelper_common_args
def dh_auto_test(*args,**kwargs):
    """ Hijack and monkey-patch dh_auto_test calls so we can set environment """
    if kwargs['buildsystem'] == 'fortran':
        tgt.dh_fortran_test(**kwargs)
    else:
        if cmplrs.is_multifortran_build():
            dh_auto_with_flavor_env(*args, **kwargs)
        noop(*args, **kwargs)

    
    
