#!/usr/bin/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_FILES = [
  ('test', 'serf_get'),
  ('test', 'serf_response'),
  ('test', 'serf_request'),
  ('test', 'serf_spider'),
  ]

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)
  builder.build_target(File('test', 'serf_response', 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(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]
  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
    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)

      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)
