#!/usr/bin/env python

"""
create the cam library
"""
#pylint: disable=multiple-imports, wrong-import-position, wildcard-import
#pylint: disable=unused-wildcard-import, bad-whitespace, too-many-locals
#pylint: disable=invalid-name
import sys, os, filecmp, shutil, imp

_CIMEROOT = os.environ.get("CIMEROOT")
if _CIMEROOT is None:
    raise SystemExit("ERROR: must set CIMEROOT environment variable")

_LIBDIR = os.path.join(_CIMEROOT, "scripts", "Tools")
sys.path.append(_LIBDIR)

from standard_script_setup import *
from CIME.case import Case
from CIME.utils import run_cmd, expect
from CIME.buildlib import parse_input
from CIME.build import get_standard_makefile_args

logger = logging.getLogger(__name__)

###############################################################################
def _build_fms(caseroot, libroot, bldroot):
###############################################################################

    with Case(caseroot) as case:

        # Only need FMS for fv3 dycore
        cam_dycore = case.get_value("CAM_DYCORE")
        if cam_dycore == 'fv3':
            # Check to see if some other component built it already
            if not os.path.exists(os.path.join(libroot,"libfms.a")):
                # first check for the external FMS library and build it
                srcroot = case.get_value("SRCROOT")
                fmsbuildlib = os.path.join(srcroot,"libraries","FMS","buildlib")
                fmsbuilddir = os.path.join(case.get_value("EXEROOT"),"FMS")
                expect(os.path.exists(fmsbuildlib), "FMS external not found")
                stat, _, err = run_cmd("{} {} {} {}".format(fmsbuildlib, case.get_value("EXEROOT"), fmsbuilddir, caseroot), verbose=True)
                expect(stat==0, "FMS build Failed {}".format(err))
                
                libfms = os.path.join(bldroot,"FMS","libfms.a")
                if os.path.exists(libfms):
                    shutil.copy(libfms, libroot)

###############################################################################
def _build_cam(caseroot, libroot, bldroot):
###############################################################################

    with Case(caseroot, read_only=False) as case:

        srcroot = case.get_value("SRCROOT")
        #-------------------------------------------------------
        # Call cam's buildcpp
        #-------------------------------------------------------
        testpath = os.path.join(srcroot, "components", "cam")
        if os.path.exists(testpath):
            srcroot = testpath

        cmd = os.path.join(os.path.join(srcroot,
                                        "cime_config", "buildcpp"))
        logger.info("     ...calling cam buildcpp to set build time options")
        try:
            mod = imp.load_source("buildcpp", cmd)
            cam_cppdefs = mod.buildcpp(case)
        except:
            raise

    with Case(caseroot) as case:

        casetools = case.get_value("CASETOOLS")
        srcroot = case.get_value("SRCROOT")
        gmake_j = case.get_value("GMAKE_J")
        gmake = case.get_value("GMAKE")
        mach = case.get_value("MACH")

        #-------------------------------------------------------
        # Filepath is created in caseroot/camconf by the call
        # to buildcpp - this needs to be copied to bldroot
        #-------------------------------------------------------
        filesrc = os.path.join(caseroot, "Buildconf", "camconf", "Filepath")
        filedst = os.path.join(bldroot, "Filepath_tmp")
        shutil.copy(filesrc, filedst)

        filedst     = os.path.join(bldroot, "Filepath")
        filedst_tmp = os.path.join(bldroot, "Filepath_tmp")
        if os.path.isfile(filedst):
            if not filecmp.cmp(filedst_tmp, filedst):
                shutil.move(filedst_tmp, filedst)
        else:
            shutil.move(filedst_tmp, filedst)

        #-------------------------------------------------------
        # build the library
        #-------------------------------------------------------
        complib  = os.path.join(libroot, "libatm.a")
        makefile = os.path.join(casetools, "Makefile")

        cmd = "{} complib -j {} MODEL=cam COMPLIB={} -f {} {} " \
            .format(gmake, gmake_j, complib, makefile, get_standard_makefile_args(case))
        if cam_cppdefs:
            cmd += " USER_CPPDEFS='{}'".format(cam_cppdefs)

        rc, out, err = run_cmd(cmd)
        logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n", cmd, out, err)
        expect(rc == 0, "Command %s failed with rc=%s" % (cmd, rc))

###############################################################################

def _main_func():
    caseroot, libroot, bldroot = parse_input(sys.argv)
    _build_fms(caseroot, libroot, bldroot)
    _build_cam(caseroot, libroot, bldroot)

###############################################################################

if __name__ == "__main__":
    _main_func()
