#!/usr/bin/env python
#
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
#
#
# gen-make.py -- generate makefiles for building Subversion
#


import os
import traceback
import sys

import getopt
try:
  my_getopt = getopt.gnu_getopt
except AttributeError:
  my_getopt = getopt.getopt
try:
  # Python >=3.0
  import configparser
except ImportError:
  # Python <3.0
  import ConfigParser as configparser

# for the generator modules
sys.path.insert(0, os.path.join('build', 'generator'))

# for getversion
sys.path.insert(1, 'build')

gen_modules = {
  'make' : ('gen_make', 'Makefiles for POSIX systems'),
  'vcproj' : ('gen_vcnet_vcproj', 'VC.Net project files'),
  }

def main(fname, gentype, verfname=None,
         skip_depends=0, other_options=None):
  if verfname is None:
    verfname = os.path.join('subversion', 'include', 'svn_version.h')

  gen_module = __import__(gen_modules[gentype][0])

  generator = gen_module.Generator(fname, verfname, other_options)

  if not skip_depends:
    generator.compute_hdr_deps()

  generator.write()
  generator.write_sqlite_headers()
  generator.write_errno_table()
  generator.write_config_keys()

  if ('--debug', '') in other_options:
    for dep_type, target_dict in generator.graph.deps.items():
      sorted_targets = sorted(target_dict.keys(), key=str)
      for target in sorted_targets:
        print(dep_type + ": " + _objinfo(target))
        for source in target_dict[target]:
          print("  " + _objinfo(source))
      print("=" * 72)
    gen_keys = sorted(generator.__dict__.keys())
    for name in gen_keys:
      value = generator.__dict__[name]
      if isinstance(value, list):
        print(name + ": ")
        for i in value:
          print("  " + _objinfo(i))
        print("=" * 72)


def _objinfo(o):
  if isinstance(o, str):
    return repr(o)
  else:
    t = o.__class__.__name__
    n = getattr(o, 'name', '-')
    f = getattr(o, 'filename', '-')
    return "%s: %s %s" % (t,n,f)


def _usage_exit(err=None):
  "print ERR (if any), print usage, then exit the script"
  if err:
    print("ERROR: %s\n" % (err))
  print("USAGE:  gen-make.py [options...] [conf-file]")
  print("  -s        skip dependency generation")
  print("  --debug   print lots of stuff only developers care about")
  print("  --release release mode")
  print("  --reload  reuse all options from the previous invocation")
  print("            of the script, except -s, -t, --debug and --reload")
  print("  -t TYPE   use the TYPE generator; can be one of:")
  items = sorted(gen_modules.items())
  for name, (module, desc) in items:
    print('            %-12s  %s' % (name, desc))
  print("")
  print("            The default generator type is 'make'")
  print("")
  print("  Makefile-specific options:")
  print("")
  print("  --assume-shared-libs")
  print("           omit dependencies on libraries, on the assumption that")
  print("           shared libraries will be built, so that it is unnecessary")
  print("           to relink executables when the libraries that they depend")
  print("           on change.  This is an option for developers who want to")
  print("           increase the speed of frequent rebuilds.")
  print("           *** Do not use unless you understand the consequences. ***")
  print("")
  print("  UNIX-specific options:")
  print("")
  print("  --installed-libs")
  print("           Comma-separated list of Subversion libraries to find")
  print("           pre-installed instead of building (probably only")
  print("           useful for packagers)")
  print("")
  print("  Windows-specific options:")
  print("")
  print("  --with-apr=DIR")
  print("           the APR sources are in DIR")
  print("")
  print("  --with-apr-util=DIR")
  print("           the APR-Util sources are in DIR")
  print("")
  print("  --with-apr-iconv=DIR")
  print("           the APR-Iconv sources are in DIR")
  print("")
  print("  --with-berkeley-db=DIR")
  print("           look for Berkeley DB headers and libs in")
  print("           DIR")
  print("")
  print("  --with-serf=DIR")
  print("           the Serf sources are in DIR")
  print("")
  print("  --with-httpd=DIR")
  print("           the httpd sources and binaries required")
  print("           for building mod_dav_svn are in DIR;")
  print("           implies --with-apr{-util, -iconv}, but")
  print("           you can override them")
  print("")
  print("  --with-libintl=DIR")
  print("           look for GNU libintl headers and libs in DIR;")
  print("           implies --enable-nls")
  print("")
  print("  --with-openssl=DIR")
  print("           tell serf to look for OpenSSL headers")
  print("           and libs in DIR")
  print("")
  print("  --with-zlib=DIR")
  print("           tell Subversion to look for ZLib headers and")
  print("           libs in DIR")
  print("")
  print("  --with-jdk=DIR")
  print("           look for the java development kit here")
  print("")
  print("  --with-junit=DIR")
  print("           look for the junit jar here")
  print("           junit is for testing the java bindings")
  print("")
  print("  --with-swig=DIR")
  print("           look for the swig program in DIR")
  print("  --with-py3c=DIR")
  print("           look for the py3c library in DIR")
  print("")
  print("  --with-sqlite=DIR")
  print("           look for sqlite in DIR")
  print("")
  print("  --with-sasl=DIR")
  print("           look for the sasl headers and libs in DIR")
  print("")
  print("  --enable-pool-debug")
  print("           turn on APR pool debugging")
  print("")
  print("  --enable-purify")
  print("           add support for Purify instrumentation;")
  print("           implies --enable-pool-debug")
  print("")
  print("  --enable-quantify")
  print("           add support for Quantify instrumentation")
  print("")
  print("  --enable-nls")
  print("           add support for gettext localization")
  print("")
  print("  --disable-shared")
  print("           only build static libraries")
  print("")
  print("  --with-static-apr")
  print("           Use static apr and apr-util")
  print("")
  print("  --with-static-openssl")
  print("           Use static openssl")
  print("")
  print("  --with-shared-serf")
  print("           Use shared library version of serf")
  print("")
  print("  --vsnet-version=VER")
  print("           generate for VS.NET version VER (2005-2017 or 9.0-15.0)")
  print("           [implies '-t vcproj']")
  print("")
  print(" -D NAME[=value]")
  print("           define NAME macro during compilation")
  print("           [only valid in combination with '-t vcproj']")
  print("")
  print("  --with-apr_memcache=DIR")
  print("           the apr_memcache sources are in DIR")
  sys.exit(1)


class Options:
  def __init__(self):
    self.list = []
    self.dict = {}

  def add(self, opt, val, overwrite=True):
    if opt in self.dict:
      if overwrite:
        self.list[self.dict[opt]] = (opt, val)
    else:
      self.dict[opt] = len(self.list)
      self.list.append((opt, val))

if __name__ == '__main__':
  try:
    opts, args = my_getopt(sys.argv[1:], 'st:D:',
                           ['debug',
                            'release',
                            'reload',
                            'assume-shared-libs',
                            'with-apr=',
                            'with-apr-util=',
                            'with-apr-iconv=',
                            'with-berkeley-db=',
                            'with-serf=',
                            'with-httpd=',
                            'with-libintl=',
                            'with-openssl=',
                            'with-zlib=',
                            'with-jdk=',
                            'with-junit=',
                            'with-swig=',
                            'with-py3c=',
                            'with-sqlite=',
                            'with-sasl=',
                            'with-apr_memcache=',
                            'with-static-apr',
                            'with-static-openssl',
                            'with-shared-serf',
                            'enable-pool-debug',
                            'enable-purify',
                            'enable-quantify',
                            'enable-nls',
                            'disable-shared',
                            'installed-libs=',
                            'vsnet-version=',
                            ])
    if len(args) > 1:
      _usage_exit("Too many arguments")
  except getopt.GetoptError:
    typ, val, tb = sys.exc_info()
    msg = ''.join(traceback.format_exception_only(typ, val))
    _usage_exit(msg)

  conf = 'build.conf'
  skip = 0
  gentype = 'make'
  rest = Options()

  if args:
    conf = args[0]

  # First merge options with previously saved to gen-make.opts if --reload
  # options used
  for opt, val in opts:
    if opt == '--reload':
      prev_conf = configparser.ConfigParser()
      prev_conf.read('gen-make.opts')
      for opt, val in prev_conf.items('options'):
        if opt != '--debug':
          rest.add(opt, val)
      del prev_conf
    elif opt == '--with-neon' or opt == '--without-neon':
      # Provide a warning that we ignored these arguments
      print("Ignoring no longer supported argument '%s'" % opt)
    else:
      rest.add(opt, val)

  # Parse options list
  for opt, val in rest.list:
    if opt == '-s':
      skip = 1
    elif opt == '-t':
      gentype = val
    elif opt == '--vsnet-version':
      gentype = 'vcproj'
    else:
      if opt == '--with-httpd':
        rest.add('--with-apr', os.path.join(val, 'srclib', 'apr'),
                 overwrite=False)
        rest.add('--with-apr-util', os.path.join(val, 'srclib', 'apr-util'),
                 overwrite=False)
        rest.add('--with-apr-iconv', os.path.join(val, 'srclib', 'apr-iconv'),
                 overwrite=False)

  # Remember all options so that --reload and other scripts can use them
  opt_conf = open('gen-make.opts', 'w')
  opt_conf.write('[options]\n')
  for opt, val in rest.list:
    opt_conf.write(opt + ' = ' + val + '\n')
  opt_conf.close()

  if gentype not in gen_modules.keys():
    _usage_exit("Unknown module type '%s'" % (gentype))

  main(conf, gentype, skip_depends=skip, other_options=rest.list)


### End of file.
