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


def cmd_install(param):
  builder = Builder(param)
  builder.install_target(File('.', 'libserf-1', '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-1', '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')
    except:
      self.libdir = '/usr/local/lib'
      self.includedir = '/usr/local/include'

    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-1', '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)
