#!/usr/bin/env python

import os
import re
import shutil
import sys
import stat

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

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