#!/usr/bin/env python

import os
import re
import shutil
import sys
import stat

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

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

  ('buckets', 'aggregate_buckets'),
  ('buckets', 'request_buckets'),
  ('buckets', 'buckets'),
  ('buckets', 'simple_buckets'),
  ('buckets', 'file_buckets'),
  ('buckets', 'mmap_buckets'),
  ('buckets', 'socket_buckets'),
  ('buckets', 'response_buckets'),
  ('buckets', 'headers_buckets'),
  ('buckets', 'allocator'),
  ('buckets', 'dechunk_buckets'),
  ('buckets', 'deflate_buckets'),
  ('buckets', 'limit_buckets'),
  ('buckets', 'ssl_buckets'),
  ('buckets', 'barrier_buckets'),
  ('buckets', 'chunk_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_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\tprefix for installed APR and APR-util')
  print('\t\t\t(needs apr-1-config and apu-1-config; will look in PATH)')
  print('\t--prefix=PATH\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('.', 'libserf-0', 'la'), False)


def cmd_install(param):
  builder = Builder(param)
  builder.install_target(File('.', 'libserf-0', '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('.', 'libserf-0', 'la')]
  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:
  def __init__(self, params):
    if 'apr' in params:
      self.apr = APRConfig(params['apr'])
      self.apu = APUConfig(params['apr'])
    else:
      self.apr = APRConfig(None)
      self.apu = APUConfig(None)

    try:
      self.libdir = os.path.join(params['prefix'], 'lib')
      self.includedir = os.path.join(params['prefix'], 'include', 'serf-0')
    except:
      self.libdir = '/usr/local/lib'
      self.includedir = '/usr/local/include/serf-0'

    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 -lssl -lcrypto'

    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

    lib = File('.', 'libserf-0', '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]), self.LIBS)
    self._add_dep(lib, libobjs, cmd)

    # load the test program dependencies now
    testhdrs = 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]), 
          self.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, self.LIBS)
        self._add_dep(prog, [lib, obj], cmd)

  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.

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

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

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

    # build the target now
    print(dep[1])
    if not dry_run:
      result = os.system(dep[1])
      if result:
        raise BuildError(dep[1], 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:

      try:
        os.makedirs(self.includedir)
        os.makedirs(self.libdir)
      except:
        pass

      for f in self.hdrs:
        shutil.copy(f.fname, self.includedir)

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

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


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