#!/usr/bin/env python

import os
import re
import shutil
import sys
import stat
import copy

### use get_version() ?
MAJOR = 1

# Basic defines for our outputs.
LIBNAME = 'libserf-%d' % (MAJOR,)
INCLUDES = 'serf-%d' % (MAJOR,)
PCFILE = 'serf-%d' % (MAJOR,)


FILES_HDR = [
  ('.', 'serf'),
  ('.', 'serf_bucket_types'),
  ('.', 'serf_bucket_util'),
  ]

LIB_FILES = [
  ('.', 'context'),
  ('.', 'incoming'),
  ('.', 'outgoing'),
  ('.', 'ssltunnel'),

  ('buckets', 'aggregate_buckets'),
  ('buckets', 'request_buckets'),
  ('buckets', 'buckets'),
  ('buckets', 'simple_buckets'),
  ('buckets', 'file_buckets'),
  ('buckets', 'mmap_buckets'),
  ('buckets', 'socket_buckets'),
  ('buckets', 'response_buckets'),
  ('buckets', 'response_body_buckets'),
  ('buckets', 'headers_buckets'),
  ('buckets', 'allocator'),
  ('buckets', 'dechunk_buckets'),
  ('buckets', 'deflate_buckets'),
  ('buckets', 'limit_buckets'),
  ('buckets', 'ssl_buckets'),
  ('buckets', 'barrier_buckets'),
  ('buckets', 'chunk_buckets'),
  ('buckets', 'iovec_buckets'),
  ('auth', 'auth'),
  ('auth', 'auth_basic'),
  ('auth', 'auth_digest'),
  ('auth', 'auth_kerb'),
  ('auth', 'auth_kerb_gss'),
  ]

TEST_DEPS = [
  ('test', 'CuTest'),
  ('test', 'test_util'),
  ('test', 'test_context'),
  ('test', 'test_buckets'),
  ('test', 'test_ssl'),
  ('test/server', 'test_server'),
  ('test/server', 'test_sslserver'),
  ]

TEST_HDR_FILES = [
  ('test', 'CuTest'),
  ('test', 'test_serf'),
  ]

TEST_FILES = [
  ('test', 'serf_get'),
  ('test', 'serf_response'),
  ('test', 'serf_request'),
  ('test', 'serf_spider'),
  ('test', 'test_all'),
  ]

TESTCASES = [
  ('test/testcases', 'simple.response'),
  ('test/testcases', 'chunked-empty.response'),
  ('test/testcases', 'chunked.response'),
  ('test/testcases', 'chunked-trailers.response'),
  ('test/testcases', 'deflate.response'),
  ]


def main(argv):
  params = {}

  commands = []

  for arg in argv[1:]:
    idx = arg.find('=')
    if idx > 0:
      start = arg.rfind('-', 0, idx)
      if start > 0:
        params[arg[start+1:idx]] = arg[idx+1:].strip()
    else:
      func = globals().get('cmd_' + arg)
      if func:
        commands.append(func)
      else:
        print('ERROR: unknown argument: ' + arg)
        usage()

  if not commands:
    usage()

  for func in commands:
    try:
      func(params)
    except:
      print('ERROR: exception:')
      print(sys.exc_info()[1])
      print("")
      usage()


def usage():
  ### print something
  print('serfmake [cmd] [options]')
  print('Commands:')
  print('\tbuild\tBuilds (default)')
  print('\tcheck\tRuns test cases')
  print('\tinstall\tInstalls serf into PREFIX')
  print('\tclean\tCleans')
  print('Options:')
  print('\t--with-apr=PATH\t\tprefix for installed APR and APR-util')
  print('\t\t\t\t(needs apr-1-config and apu-1-config; will look in PATH)')
  print('\t--with-gssapi=PATH\tbuild serf with GSSAPI support')
  print('\t\t\t\t(needs krb5-config; will look in PATH/bin)')

  print('\t--prefix=PATH\t\tinstall serf into PATH (default: /usr/local)')
  print('Quick guide:')
  print('\tserfmake --prefix=/usr/local/serf --with-apr=/usr/local/apr install')
  sys.exit(1)


def cmd_build(param):
  builder = Builder(param)
  builder.build_target(File('.', LIBNAME, 'la'), False)
  builder.build_target(File('.', PCFILE, 'pc'), False)


def cmd_install(param):
  builder = Builder(param)
  builder.build_target(File('.', PCFILE, 'pc'), False) 
  ### should be called .install_all()
  builder.install_target(File('.', LIBNAME, 'la'), False)


def cmd_check(param):
  builder = Builder(param)
  for dirpath, fname in TEST_FILES:
    builder.build_target(File(dirpath, fname, None), False)

  for dirpath, fname in TESTCASES:
    case = os.path.join(dirpath, fname)
    print('== Testing %s ==' % case)
    result = os.system('%s %s' % (os.path.join('test', 'serf_response'), case))
    if result:
      raise TestError("", result)

  # run the test suite based on the CuTest framework
  result = os.system(os.path.join('test', 'test_all'))
  if result:
    raise TestError(case, result)  

def cmd_clean(param):
  targets = [File(dirpath, fname, 'o') for dirpath, fname in LIB_FILES]
  targets += [File(dirpath, fname, 'lo') for dirpath, fname in LIB_FILES]
  targets += [File('.', LIBNAME, 'la'),
              File('.', PCFILE, 'pc'),
              ]
  targets += [File(dirpath, fname, 'o') for dirpath, fname in TEST_FILES]
  targets += [File(dirpath, fname, 'lo') for dirpath, fname in TEST_FILES]
  targets += [File(dirpath, fname, None) for dirpath, fname in TEST_FILES]
  targets += [File(dirpath, fname, 'o') for dirpath, fname in TEST_DEPS]
  targets += [File(dirpath, fname, 'lo') for dirpath, fname in TEST_DEPS]

  clean = [file for file in targets if file.mtime]
  if clean:
    sys.stdout.write('Cleaning %d files... ' % len(clean))
    for i in clean:
      if i.mtime:
        os.remove(i.fname)
    print('done.')
  else:
    print('Clean.')


class Builder(object):
  def __init__(self, params):
    # use apr option if set
    if 'apr' in params:
      self.apr = APRConfig(params['apr'])
      self.apu = APUConfig(params['apr'])
    else:
      self.apr = APRConfig(None)
      self.apu = APUConfig(None)

    # build with gssapi if option is set
    if 'gssapi' in params:
      self.gssapi = GSSAPIConfig(params['gssapi'])
    else:
      self.gssapi = None

    try:
      self.prefix = params['prefix']
    except:
      self.prefix = '/usr/local'

    ### no way to tweak these
    self.libdir = os.path.join(self.prefix, 'lib')
    self.pkgconfigdir = os.path.join(self.prefix, 'lib', 'pkgconfig')
    self.includedir = os.path.join(self.prefix, 'include', INCLUDES)

    self.load_vars()
    self.load_deps()

  def load_vars(self):
    self.CC = self.apr.get_value('CC', '--cc')
    self.CFLAGS = self.apr.get_value('CFLAGS', '--cflags')
    self.CPPFLAGS = self.apr.get_value('CPPFLAGS', '--cppflags')
    self.LIBTOOL = self.apr.get_value('LIBTOOL', '--apr-libtool')
    self.LDFLAGS = self.apr.get_value('LDFLAGS', '--ldflags') \
                   + ' ' + self.apu.get_value('LDFLAGS', '--ldflags')

    self.INCLUDES = '-I%s -I%s -I%s' % (
      '.',
      self.apr.get_value(None, '--includedir'),
      self.apu.get_value(None, '--includedir'),
      )
    if os.getenv('EXTRA_INCLUDES'):
      self.INCLUDES += ' -I' + os.getenv('EXTRA_INCLUDES')

    self.LIBS = self.apu.get_value(None, '--link-libtool') \
                + ' ' + self.apu.get_value(None, '--libs') \
                + ' ' + self.apr.get_value(None, '--link-libtool') \
                + ' ' + self.apr.get_value(None, '--libs') \
                + ' -lz'
    self.SSL_LIBS = '-lssl -lcrypto'
    if self.gssapi:
        self.LIBS += ' ' + self.gssapi.get_value(None, '--libs gssapi')
        self.CFLAGS += ' ' + self.gssapi.get_value('CFLAGS', '--cflags gssapi')\
                       + ' -DSERF_HAVE_GSSAPI -g'

    self.MODE = 644

  def load_deps(self):
    self.deps = { }

    hdrs = [File(dirpath, fname, 'h') for dirpath, fname in FILES_HDR]
    libfiles = [File(dirpath, fname, 'c') for dirpath, fname in LIB_FILES]
    libobjs = [File(dirpath, fname, 'lo') for dirpath, fname in LIB_FILES]
    for src, obj in zip(libfiles, libobjs):
      self._add_compile(src, obj, hdrs)

    self.hdrs = hdrs

    all_libs = self.LIBS + ' ' + self.SSL_LIBS

    lib = File('.', LIBNAME, 'la')
    cmd = '%s --silent --mode=link %s %s -rpath %s -o %s %s %s' % (
      self.LIBTOOL, self.CC, self.LDFLAGS, self.libdir,
      lib.fname, ' '.join([l.fname for l in libobjs]), all_libs)
    self._add_dep(lib, libobjs, cmd)

    # load the test program dependencies now
    testhdrs = copy.deepcopy(hdrs)
    testhdrs += [File(dirpath, fname, 'h') for dirpath, fname in TEST_HDR_FILES]
    testdeps = [File(dirpath, fname, 'c') for dirpath, fname in TEST_DEPS]
    testobjs = [File(dirpath, fname, 'lo') for dirpath, fname in TEST_DEPS]

    for testsrc, testobj in zip(testdeps, testobjs):
      self._add_compile(testsrc, testobj, testhdrs)

    for dirpath, fname in TEST_FILES:
      src = File(dirpath, fname, 'c')
      obj = File(dirpath, fname, 'lo')
      prog = File(dirpath, fname, None)

      self._add_compile(src, obj, hdrs)

      # test_all requires extra dependencies
      if fname == "test_all":
        cmd = '%s --silent --mode=link %s %s -static -o %s %s %s %s' % (
          self.LIBTOOL, self.CC, self.LDFLAGS,
          prog.fname, lib.fname, ' '.join([l.fname for l in [obj] + testobjs]), 
          all_libs)
        self._add_dep(prog, [lib, obj] + testobjs, cmd)
      else:
        cmd = '%s --silent --mode=link %s %s -static -o %s %s %s %s' % (
          self.LIBTOOL, self.CC, self.LDFLAGS,
          prog.fname, lib.fname, obj.fname, all_libs)
        self._add_dep(prog, [lib, obj], cmd)

    # create 'serf-1.pc' if it doesn't exist.
    pcfile = File('.', PCFILE, 'pc')
    self._add_dep(pcfile, [], self._write_pcfile)

  def _add_compile(self, src, obj, hdrs):
    cmd = '%s --silent --mode=compile %s %s %s %s -c -o %s %s' % (
      self.LIBTOOL, self.CC, self.CFLAGS, self.CPPFLAGS, self.INCLUDES,
      obj.fname, src.fname)
    self._add_dep(obj, [src] + hdrs, cmd)

  def _add_dep(self, target, deps, cmd):
    if target.mtime:
      for dep in deps:
        if dep in self.deps or (dep.mtime and dep.mtime > target.mtime):
          # a dep is newer. this needs to be rebuilt.
          break
      else:
        # this is up to date. don't add it to the deps[] structure.
        return
    # else non-existent, so it must be rebuilt.

    # Commands that are strings are cmdline invocations. Otherwise, it
    # should be a callable.
    if isinstance(cmd, str):
      cmd = CommandLine(cmd)

    # register the dependency so this will get built
    self.deps[target] = deps, cmd

  def _write_pcfile(self):
    """Generating serf-1.pc ..."""

    open(PCFILE + '.pc', 'w').write(
"""SERF_MAJOR_VERSION=%d
prefix=%s
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/%s

Name: serf
Description: HTTP client library
Version: %s
Requires.private: libssl libcrypto
Libs: -L${libdir} -lserf-${SERF_MAJOR_VERSION}
Libs.private: %s
Cflags: -I${includedir}
""" % (MAJOR, self.prefix, INCLUDES, get_version(), self.LIBS))

  def build_target(self, target, dry_run):
    deps, cmd = self.deps.get(target, (None, None))
    if cmd is None:
      # it's already up to date. all done.
      return

    for f in deps:
      subdep = self.deps.get(f)
      if subdep:
        self.build_target(f, dry_run)

    # build the target now
    print(cmd.__doc__)
    if not dry_run:
      result = cmd()
      if result:
        raise BuildError(cmd.__doc__, result)
      # FALLTHROUGH

    # it's a dry run. pretend we built the target.
    del self.deps[target]
    return 0

  def install_target(self, target, dry_run):
    self.build_target(target, dry_run)

    # install the target now
    if not dry_run:

      for path in (self.libdir, self.pkgconfigdir, self.includedir):
        if not os.path.exists(path):
          try:
            os.makedirs(path)
          except OSError:
            raise BuildError('os.makedirs',
                             'can not create install directories')

      for f in self.hdrs:
        print("Installing: %s" % (os.path.basename(f.fname),))
        shutil.copy(f.fname, self.includedir)

      print("Installing: %s.pc" % (PCFILE,))
      shutil.copy(PCFILE + '.pc', self.pkgconfigdir)

      cmd = '%s --silent --mode=install %s -c -m %d %s %s' % (
            self.LIBTOOL, '/usr/bin/install', self.MODE, target.fname,
            self.libdir)

      print("Installing: %s" % (os.path.basename(target.fname),))
      result = os.system(cmd)
      if result:
        raise BuildError(cmd, result)
      # FALLTHROUGH

    return 0


class ConfigScript(object):
  script_name = None
  locations = [
    '/usr/bin',
    '/usr/local/bin',
    '/usr/local/apache2/bin',
    ]

  def __init__(self, search_dir):
    if search_dir:
      locations = [search_dir, os.path.join(search_dir, 'bin')]
    else:
      locations = self.locations

    for dirname in locations:
      bin = os.path.join(dirname, self.script_name)
      if os.access(bin, os.X_OK):
        self.bin = bin
        break
    else:
      raise ConfigScriptNotFound(self.script_name)

  def get_value(self, env_name, switch):
    if env_name and os.getenv(env_name):
      return os.getenv(env_name)
    return os.popen('%s %s' % (self.bin, switch), 'r').read().strip()


class APRConfig(ConfigScript):
  script_name = 'apr-1-config'


class APUConfig(ConfigScript):
  script_name = 'apu-1-config'


class GSSAPIConfig(ConfigScript):
  script_name = 'krb5-config'


class CommandLine(object):
  """Simple helper to invoke a system command when called."""

  def __init__(self, cmd):
    self.cmd = cmd
    self.__doc__ = cmd  # when we print the execution of this command

  def __call__(self):
    return os.system(self.cmd)


class File:
  def __init__(self, dirpath, fname, ext):
    if ext:
      self.fname = os.path.join(dirpath, fname + '.' + ext)
    else:
      self.fname = os.path.join(dirpath, fname)

    try:
      s = os.stat(self.fname)
    except OSError:
      self.mtime = None
    else:
      self.mtime = s[stat.ST_MTIME]

  def __eq__(self, other):
    return self.fname == other.fname

  def __hash__(self):
    return hash(self.fname)


def get_version():
  match = re.search('SERF_MAJOR_VERSION ([0-9]+).*'
                    'SERF_MINOR_VERSION ([0-9]+).*'
                    'SERF_PATCH_VERSION ([0-9]+)',
                    open('serf.h').read(),
                    re.DOTALL)
  major, minor, patch = match.groups()
  return '%s.%s.%s' % (major, minor, patch)


class BuildError(Exception):
  "An error occurred while building a target."
class TestError(Exception):
  "An error occurred while running a unit test."
class ConfigScriptNotFound(Exception):
  def __init__(self, value):
    self.value = "ERROR: A configuration script was not found: " + value
  def __str__(self):
    return self.value


if __name__ == '__main__':
  main(sys.argv)


###
### TODO:
### * obey DESTDIR
### * arfrever says LDFLAGS is passed twice
### * be able to specify libdir and includedir
###
