#!/usr/bin/env python
#
# Copyright (C) 2005-2018 ABINIT Group (Yann Pouillon)
#
# This file is part of the ABINIT software package. For license information,
# please see the COPYING file in the top-level directory of the ABINIT source
# distribution.
#
from __future__ import print_function, division, absolute_import #, unicode_literals

try:
    from ConfigParser import ConfigParser
except ImportError:
    from configparser import ConfigParser
from time import gmtime,strftime

import os
import re
import sys

class MyConfigParser(ConfigParser):

  def optionxform(self,option):
    return str(option)

# ---------------------------------------------------------------------------- #

#
# Subroutines
#

# Makefile header
def makefile_header(name,stamp):

  return """#
# Makefile for ABINIT                                      -*- Automake -*-
# Generated by %s on %s

#
# IMPORTANT NOTE
#
# Any manual change to this file will systematically be overwritten.
# Please modify the %s script or its config file instead.
#

""" % (name,stamp,name)



def makefile_subdirs(filename,prefix):

  ret       = ""
  re_begin  = re.compile("^## BEGIN BUILD$")
  re_end    = re.compile("^## END BUILD$")
  tmp       = open(filename, "rt").readlines()
  save_line = False

  for line in tmp:
    if ( re_end.match(line) ):
      save_line = False
    if ( save_line ):
      ret += line
    if ( re_begin.match(line) ):
      save_line = True

  ret = re.sub("#","",ret).strip().split()
  ret = ["$(%s%s)" % (prefix,x) for x in ret]

  return ret



# ---------------------------------------------------------------------------- #

#
# Main program
#

# Initial setup
my_name    = "make-makefiles-inter"
my_configs = {
  "libs":"config/specs/corelibs.conf"}

sep = "# ---------------------------------------------------------------------------- #\n\n"

# Check if we are in the top of the ABINIT source tree
if ( not os.path.exists("configure.ac") or
     not os.path.exists("src/98_main/abinit.F90") ):
  print("%s: You must be in the top of an ABINIT source tree." % my_name)
  print("%s: Aborting now." % my_name)
  sys.exit(1)

# Read config file(s)
for cnf_file in my_configs.values():
  if ( os.path.exists(cnf_file) ):
    if ( re.search("\.cf$",cnf_file) ):
      exec(compile(open(cnf_file).read(), cnf_file, 'exec'))
  else:
    print("%s: Could not find config file (%s)." % (my_name,cnf_file))
    print("%s: Aborting now." % my_name)
    sys.exit(2)

# What time is it?
now = strftime("%Y/%m/%d %H:%M:%S +0000",gmtime())

# Generate library lists
src_list = "SUBDIRS ="
opt_list = ""
lib_list = ""
sub_lib_list = "SUBDIRS ="
pin_list = ""
sub_pin_list = "SUBDIRS ="

tgt_abirules = "# Enforce ABINIT Coding Style (the so-called ABIRULES)\n" + \
  "abirules:\n\t@echo 'Reporting possible errors in the abirules procedure'" + \
  " > tmp-abirules.log\n"

# Preset lists
src_list += " \\\n\tincs"
src_list += " \\\n\tmods"

# Core libraries
cnf = MyConfigParser()
cnf.read(my_configs["libs"])
abinit_corelibs = cnf.sections()
abinit_corelibs.sort()
for lib in abinit_corelibs:
  lib_opt = cnf.get(lib,"optional")
  lib_rul = cnf.get(lib,"abirules")

  if ( lib_opt == "yes" ):
    src_list += " \\\n\t$(core_%s)" % (lib)
    opt_list += "if DO_BUILD_%s\n core_%s = %s\nelse\n core_%s =\nendif\n" % \
      (lib.upper(),lib,lib,lib)
  else:
    src_list += " \\\n\t"+lib

  if ( lib_rul == "yes" ):
    tgt_abirules += "\t@$(PERL) ../developers/maintainers/abirules.pl -d %s >> abirules.log\n" % (lib)

opt_list += "\n" 
src_list += " \\\n\t98_main\n"
src_list += "if DO_BUILD_EXPORTS\n SUBDIRS += libs\nendif\n\n"
tgt_abirules += "\t@$(PERL) ../developers/maintainers/abirules.pl -d 98_main >> abirules.log\n"
tgt_abirules += "\tcd .. ; ./config/scripts/abilint . . > src/abilint.log ; cd src\n"
tgt_abirules += "\t@grep 'Error' abirules.log \n\n"

# Write Makefile.am for includes
tmpdir = re.compile("tmp-*")
vimswp = re.compile("\..*\.swp")
makefile  = "all-local:\n\t@echo \"There is no buildable file here\"\n\n"
makefile += "EXTRA_DIST ="
for root,dirs,files in os.walk("src/incs"):
  for sub in dirs:
    if ( tmpdir.match(sub) ):
      dirs.remove(sub)
  if ( "Makefile.am" in files ):
    files.remove("Makefile.am")
  if ( "Makefile.in" in files ):
    files.remove("Makefile.in")
  if ( "Makefile" in files ):
    files.remove("Makefile")
  for dat in files:
    if ( vimswp.match(dat) ):
      files.remove(dat)
  dirs.sort()
  files.sort()
  for dat in files:
    makefile += " \\\n\t%s" % (dat)
makefile += "\n"
mf = open("src/incs/Makefile.am", "wt")
mf.write(makefile_header(my_name,now))
mf.write(makefile)
add = "config/makefiles/incs.am"
if ( os.path.exists(add) ):
  mf.write(sep + open(add,"rt").read())
mf.close()

# Write Makefile.am for modules
mf = open("src/mods/Makefile.am", "wt")
mf.write(makefile_header(my_name,now))
mf.write("all-local:\n\t@echo \"There is no buildable file here\"\n\n")
add = "config/makefiles/mods.am"
if ( os.path.exists(add) ):
  mf.write(sep + open(add, "rt").read())
mf.close()

# Write intermediate Makefile.am for core source
mf = open("src/Makefile.am", "wt")
mf.write(makefile_header(my_name,now))
mf.write(opt_list+src_list)
mf.write(sep+tgt_abirules)
add = "config/makefiles/src.am"
if ( os.path.exists(add) ):
  mf.write(sep + open(add, "rt").read())
mf.close()
