#!/usr/bin/env python3
import os, sys, logging, argparse

from standard_script_setup import *
from CIME import utils
from CIME.config import Config
from CIME.utils import copyifnewer, run_bld_cmd_ensure_logging
from CIME.case import Case
from CIME.build import get_standard_makefile_args
import glob

sys.path.append(os.path.dirname(__file__))
from buildlib_util import extract_from_macros

logger = logging.getLogger(__name__)

###############################################################################
def parse_command_line(args, description):
###############################################################################
    parser = argparse.ArgumentParser(
        usage="""\n{0} [--debug]
OR
{0} --verbose
OR
{0} --help

\033[1mEXAMPLES:\033[0m
    \033[1;32m# Run \033[0m
    > {0}
""".format(
            os.path.basename(args[0])
        ),
        description=description,
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )

    utils.setup_standard_logging_options(parser)

    parser.add_argument("buildroot", help="build path root")

    parser.add_argument("installpath", help="install path ")

    parser.add_argument(
        "caseroot", nargs="?", default=os.getcwd(), help="Case directory to build"
    )

    args = utils.parse_args_and_handle_standard_logging_options(args, parser)

    return args.buildroot, args.installpath, args.caseroot

###############################################################################
def buildlib(bldroot, installpath, case):
###############################################################################
    caseroot  = case.get_value("CASEROOT")
    srcroot   = case.get_value("SRCROOT")
    gmake_cmd = case.get_value("GMAKE")
    gmake_j   = case.get_value("GMAKE_J")
    mpilib    = case.get_value("MPILIB")

    customize_path = os.path.join(srcroot, "cime_config", "customize")

    config = Config.load(customize_path)

    mct_path = config.mct_path.format(srcroot=srcroot)
    mpi_serial_path = os.path.join(mct_path, "mpi-serial")

    for _file in glob.iglob(os.path.join(mpi_serial_path, "*.h")):
        copyifnewer(_file, os.path.join(bldroot, os.path.basename(_file)))

    fc, cc, _, _, _, _, fflags, cflags, _, cppdefs, ldflags, ffree, config_args = \
        extract_from_macros(case, "mpi-serial", extra_vars=("CMAKE_Fortran_FORMAT_FREE_FLAG", "CONFIG_ARGS"))

    fflags += f" {ffree}"

    # Only need the netcdf_c library
    if "NETCDF_PATH" in os.environ:
        netcdf_args = f"NETCDF_PATH={os.environ['NETCDF_PATH']} "
    elif "NETCDF_C_PATH" in os.environ:
        netcdf_args = f"NETCDF_PATH={os.environ['NETCDF_C_PATH']} "

    config_cmd = f"{mpi_serial_path}/configure CC={cc} FC={fc} FCFLAGS='{fflags}' CPPDEFS='{cppdefs}' CFLAGS='{cflags}' LDFLAGS='{ldflags}' {config_args} {netcdf_args} --srcdir {mpi_serial_path}"

    # run configure
    run_bld_cmd_ensure_logging(config_cmd, logger, from_dir=bldroot)

    # Now we run the mpi-serial make command
    gmake_opts = "-f {} ".format(os.path.join(mpi_serial_path, "Makefile"))
    gmake_opts += " -C {} ".format(bldroot)
    gmake_opts += " -j {} ".format(case.get_value("GMAKE_J"))
    gmake_opts += " SRCDIR={} ".format(os.path.join(mct_path))

    cmd = "{} {}".format(gmake_cmd, gmake_opts)
    run_bld_cmd_ensure_logging(cmd, logger)

    copyifnewer(
        os.path.join(bldroot, "libmpi-serial.a"),
        os.path.join(installpath, "lib", "libmpi-serial.a"),
    )
    for _file in ("mpi.h", "mpif.h", "mpi.mod", "MPI.mod"):
        if os.path.isfile(os.path.join(bldroot, _file)):
            copyifnewer(
                os.path.join(bldroot, _file),
                os.path.join(installpath, "include", _file),
            )

###############################################################################
def _main(argv, documentation):
###############################################################################
    bldroot, installpath, caseroot = parse_command_line(argv, documentation)
    with Case(caseroot) as case:
        buildlib(bldroot, installpath, case)

###############################################################################
if __name__ == "__main__":
    _main(sys.argv, __doc__)
