# -*- coding: utf-8 -*-

# Copyright (C) 2009, INERIS - INRIA
# Author(s): Édouard Debry, Vivien Mallet
#
# This file is part of the air quality modeling system Polyphemus.
#
# Polyphemus is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# Polyphemus is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# For more information, visit the Polyphemus web site:
#      http://cerea.enpc.fr/polyphemus/


import os, glob, sys


###################
# USEFUL FUNCTION #
###################


# Returns 'default' if the variable with name 'input_name' is not in the
# global namespace; returns the variable otherwise.
def create_variable(input_name, default):
    exec("global " + input_name)
    try:
        exec("local_copy = " + input_name)
        if local_copy is None:
            return default
        else:
            return local_copy
    except:
        return default


# Returns the input as a list of strings, if the input is a list of strings, a
# string, None, or if the input can be converted to string. The input must be
# provided as a string containing its name.
def to_string_list(input_name):
    exec("global " + input_name)
    try:
        exec("local_copy = " + input_name)
    except:
        return []
    if local_copy is None:
        return []
    elif isinstance(local_copy, list):
        return local_copy
    else:
        return Split(str(local_copy))


#################
# CONFIGURATION #
#################

# Path to Polyphemus.
polyphemus_path = create_variable("polyphemus_path",
                                  os.path.abspath("../../../"))
# Path to Verdandi.
verdandi_path = os.path.join(polyphemus_path, "include/verdandi/")

if not os.path.isdir(verdandi_path):
    print "[ERROR] In \"models/chimere\":"
    print "    Verdandi not found at \"" + verdandi_path + "\"."
    print "    Please install Verdandi to use the Chimere model."
    Return()

# For NetCDF compiled with g95.
library_path = create_variable("library_path", "")
# Lam-mpi include path
lam_include_path = create_variable("lam_include_path", "/usr/include/lam/")

# Automatically retrieved from the environment ("chimere_tmp" should be set by
# "chimere.sh").
if os.environ.has_key("chimere_tmp"):
    chimere_tmp_path = os.environ["chimere_tmp"]
else:
    chimere_tmp_path = "/tmp/"


##########################
# ENVIRONMENT DEFINITION #
##########################


# Main environment variables.
env = Environment(ENV = os.environ)

env.Replace(F90FLAGS = "-fno-second-underscore")

include_directory_cpp = ["/usr/include", "include",
                         "include/Talos", "include/newran",
                         "include/SeldonData", "include/AtmoData",
                         "include/models", "include/models/chimere",
                         "include/driver/common",
                         "include/driver/common/output_saver",
                         "include/driver/common/observation",
                         "include/driver/common/perturbation",
                         "include/driver/uncertainty"] \
                         + [lam_include_path] \
                         + [verdandi_path,
                            os.path.join(verdandi_path, "include/lua/src")]

include_directory_f90 = [os.path.join(chimere_tmp_path, "tools"),
                         os.path.join(chimere_tmp_path, "initio"),
                         os.path.join(chimere_tmp_path, "iso"),
                         os.path.join(chimere_tmp_path, "main"),
                         os.path.join(chimere_tmp_path, "model"),
                         os.path.join(chimere_tmp_path, "modules")]
object_f90 = [Glob(directory + "/*.o") for directory in include_directory_f90]

include_path_list_cpp = []
for path in include_directory_cpp:
    if os.path.isdir(path):
        include_path_list_cpp.append(path)
    elif os.path.isdir(os.path.join(polyphemus_path, path)):
        include_path_list_cpp.append(os.path.join(polyphemus_path, path))
    else:
        raise Exception, "Unable to find the include directory \"" \
            + path + "\" (even in Polyphemus directory, \"" \
            + polyphemus_path + "\")."

env.Append(CPPPATH = include_path_list_cpp)
env.Append(F90PATH = include_directory_f90)

os.environ["LAMMPIF77"] = "g95"
os.environ["LAMMPICXX"] = "g++"
env.Replace(CPP = "mpic++")
env.Replace(F90 = "mpif90")
env.Replace(LINK = "mpic++")

library_path = to_string_list("library_path")
for path in library_path:
    if os.path.isdir(path):
        env.Append(LIBPATH = [path])
    elif os.path.isdir(os.path.join(polyphemus_path, path)):
        env.Append(LIBPATH = [os.path.join(polyphemus_path, path)])
    else:
        raise Exception, "Unable to find the library directory \"" \
              + path + "\" (even in Polyphemus directory, \"" \
              + polyphemus_path + "\")."

conf = Configure(env)
library_list = to_string_list("library_list")
for library in ["hdf5", "hdf5_hl", "netcdf", "f95", "newran", "lua",
                "blas", "atlas", "cblas", "lapack", "g2c", "gslcblas",
                "gfortran", "cppunit", "python"]:
    if library not in library_list:
        library_list += [library]
for library in library_list:
    conf.CheckLib(library)


##########
# TARGET #
##########


file_f90 = ["chimere_aerosol_anthropic_emission.f90",
            "chimere_perturbation.f90",
            "cleanup.f90",
            "forward.f90",
            "forward_integrun.f90",
            "forward_worker.f90",
            "initstep.f90",
            "initstep_integrun.f90",
            "initstep_worker.f90",
            "init.f90",
            "init_integrun.f90",
            "init_worker.f90",
            "get_routines.f90"]
file_f90 = [os.path.join(polyphemus_path, "include/models/chimere/" + s)
            for s in file_f90]

target_list = glob.glob("*.cpp")
for filename in target_list:
    env.Program(filename[:-4],
                [filename, object_f90, file_f90,
                 os.path.join(verdandi_path, "include/lua/src/liblua.a")])
