#!/usr/bin/env python
#
# Copyright (C) 2009-2010 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 time import gmtime,strftime

import commands
import os
import re
import sys

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

#
# Subroutines
#

# Macro header
def macro_header(name,stamp):

  return """# Generated by %s on %s

#
# ABINIT plug-in support for the "configure" script
#

#
# IMPORTANT NOTE
#
# This file has been automatically generated by the %s
# script. If you try to edit it, your changes will systematically be
# overwritten.
#
""" % (name,stamp,name)



# Autotools info macro
def macro_info(m4_version,ac_version,am_version,lt_version):

  return """


# ABI_INFO_AUTOTOOLS()
# --------------------
#
# Make information about the Autotools available.
#
AC_DEFUN([ABI_INFO_AUTOTOOLS],[
  dnl Store version numbers
  abi_m4_version="%6.6d"
  abi_ac_version="%6.6d"
  abi_am_version="%6.6d"
  abi_lt_version="%6.6d"

  dnl Display version information
  AC_MSG_NOTICE([M4 ${abi_m4_version} - Autoconf ${abi_ac_version} - Automake ${abi_am_version} - Libtool ${abi_lt_version}])

  dnl Substitute variables
  AC_SUBST(abi_m4_version)
  AC_SUBST(abi_ac_version)
  AC_SUBST(abi_am_version)
  AC_SUBST(abi_lt_version)
]) # ABI_INFO_AUTOTOOLS
""" % (m4_version,ac_version,am_version,lt_version)



# Init macro for source and build dirs
def macro_init_dirs(ac_version):

  if ( ac_version > 25900 ):
    ac_macro = "_AC_SRCDIRS"
  else:
    ac_macro = "_AC_SRCPATHS"

  ret = """


# ABI_INIT_DIRS()
# ---------------
#
# Set paths to source and build directories.
#
AC_DEFUN([ABI_INIT_DIRS],[
  dnl Set paths (needed by other ABINIT macros)
  %s(["."])
  abinit_srcdir="${ac_abs_top_srcdir}"
  abinit_builddir="${ac_abs_top_builddir}"
  abinit_moddir="${abinit_builddir}/src/mods"

  export abinit_srcdir abinit_builddir

  AC_SUBST(abinit_srcdir)
  AC_SUBST(abinit_builddir)
  AC_SUBST(abinit_moddir)
]) # ABI_INIT_DIRS
""" % (ac_macro)

  return ret



def translate_version(version_string):

  # Init
  ret = version_string
  ret = ret.split(".")

  # Force x.y.z version numbers
  while ( len(ret) < 3 ):
    ret.append("0")
  if ( len(ret) > 3 ):
    ret = ret[0:3]

  # Force 2 digits
  for i in range(len(ret)):
    try:
      if ( int(ret[i]) < 10 ):
        ret[i] = "0"+ret[i]
      elif ( int(ret[i]) > 99 ):
        sys.stderr.write("%s: Error: cannot handle 3-digit version numbers\n" % (my_name))
        sys.exit(1)
    except ValueError:
      # [2010-04-20] The last version of libtool is 2.2.6b, this solve that case 
      if ( ret[i] == "6b" or ret[i] == "6a" ):
        ret[i] = "06"
      else:
        sys.stderr.write("%s: WARNING: invalid version number %s set to 0\n" % (my_name,ret[i]))
        ret[i] = "00"

  # Finish
  ret = int("".join(ret))

  return ret



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

#
# Main program
#

# Initial setup
my_name    = "make-macros-autotools"
my_output  = "config/m4/auto-autotools.m4"

# 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)

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

# Get Autotools versions
(m4_ret,m4_version) = commands.getstatusoutput("m4 --version | sed 's/o/ /g' ")
(ac_ret,ac_version) = commands.getstatusoutput("autoconf --version")
(am_ret,am_version) = commands.getstatusoutput("automake --version")
(lt_ret,lt_version) = commands.getstatusoutput("libtool  --version")

# Extract and process version numbers
if ( m4_ret == 0 ):
  m4_version = m4_version.split("\n")[0]
  m4_version = re.sub(r"^(GNU [Mm]4|m4 \(GNU M4\)) ","",m4_version)
  m4_version = re.sub(" .*","",m4_version)
  m4_version = translate_version(m4_version)
else:
  m4_version = 0

if ( ac_ret == 0 ):
  ac_version = ac_version.split("\n")[0]
  ac_version = re.sub(".*\(GNU Autoconf\) ","",ac_version)
  ac_version = re.sub(" .*","",ac_version)
  ac_version = translate_version(ac_version)
else:
  ac_version = 0

if ( am_ret == 0 ):
  am_version = am_version.split("\n")[0]
  am_version = re.sub(".*\(GNU automake\) ","",am_version)
  am_version = re.sub(" .*","",am_version)
  am_version = translate_version(am_version)
else:
  am_version = 0

if ( lt_ret == 0 ):
  lt_version = lt_version.split("\n")[0]
  lt_version = re.sub(".*\(GNU libtool\) ","",lt_version)
  lt_version = re.sub(" .*","",lt_version)
  lt_version = translate_version(lt_version)
else:
  lt_version = 0

if ( m4_version < 10408 ):
  sys.stderr.write("%s: Error: M4 is too old (%d) - " % (my_name,m4_version) \
    + "please install v1.4.8 or above\n%s: Aborting now\n" % (my_name))
  sys.exit(10)

if ( ac_version < 26100 ):
  sys.stderr.write("%s: Error: Autoconf is too old (%d) - " % (my_name,ac_version) \
    + "please install v2.61 or above\n%s: Aborting now\n" % (my_name))
  sys.exit(20)

if ( am_version < 11000 ):
  sys.stderr.write("%s: Error: Automake is too old (%d) - " % (my_name,am_version) \
    + "please install v1.10 or above\n%s: Aborting now\n" % (my_name))
  sys.exit(30)

# Write macros
m4 = file(my_output,"w")
m4.write(macro_header(my_name,now))
m4.write(macro_info(m4_version,ac_version,am_version,lt_version))
m4.write(macro_init_dirs(ac_version))
m4.close()

# Make version information available to makemake
ai = file("config/local/autotools.sh","w")
ai.write("""# Autotools version information
abi_m4_version="%6.6d"
abi_ac_version="%6.6d"
abi_am_version="%6.6d"
abi_lt_version="%6.6d"
""" % (m4_version,ac_version,am_version,lt_version))
ai.close()

tmp = commands.getoutput("./config/scripts/add-header-typed Autoconf %s" % (my_output))
if ( tmp != "" ):
  print tmp
