#!/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'),

  ('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'),
  ]

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 = {}

  cmd = None

  for i in argv[1:]:
    idx = i.find('=')
    if idx > 0:
      start = i.rfind('-', 0, idx)
      if start > 0:
        params[i[start+1:idx]] = i[idx+1:].strip()
    elif not cmd:
      cmd = i

  if not cmd:
    cmd = 'build'
 
  func = globals().get('cmd_' + cmd)
  if not func:
    print 'ERROR: no such command:', cmd
    usage()

  try:
    func(params)
  except Exception, e:
    print e
    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):
  clean = [File(dirpath, fname, 'o') for dirpath, fname in LIB_FILES]
  clean += [File(dirpath, fname, 'lo') for dirpath, fname in LIB_FILES]
  clean += [File('.', 'libserf-0', 'la')]
  clean += [File(dirpath, fname, 'o') for dirpath, fname in TEST_FILES]
  clean += [File(dirpath, fname, 'lo') for dirpath, fname in TEST_FILES]
  clean += [File(dirpath, fname, None) for dirpath, fname in TEST_FILES]
  clean += [File(dirpath, fname, 'o') for dirpath, fname in TEST_DEPS]
  clean += [File(dirpath, fname, 'lo') for dirpath, fname in TEST_DEPS]
  for i in clean:
    if i.mtime:
      os.remove(i.fname)

class Builder:
  def __init__(self, params):
    try:
      self.apr = APRConfig(params['apr'])
      self.apu = APUConfig(params['apr'])
    except:
      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 self.deps.has_key(dep) \
               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:
      self.locations.append(search_dir)
      self.locations.append(os.path.join(search_dir, 'bin'))
    for dirname in self.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 __cmp__(self, other):
    return cmp(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)
