#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
import os, re, sys, string, platform
from distutils.core import setup, Command
from distutils.command.build import build as _build
from distutils.command.build_py import build_py as _build_py
from distutils.command.clean import clean as _clean
from distutils.command.install_lib import install_lib as _install_lib
from distutils.dep_util import newer
from distutils.dir_util import remove_tree
from distutils.dist import Distribution
from distutils.errors import DistutilsFileError, DistutilsOptionError
from distutils import log
from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE

MAJOR, MINOR = sys.version_info[0:2]

class preprocessor:

  def copy_file(self, src, dst, preserve_mode=1, preserve_times=1,
                link=None, level=1):
    name, actor = self.actor(src, dst)
    if actor:
      if not os.path.isfile(src):
        raise DistutilsFileError, \
            "can't copy '%s': doesn't exist or not a regular file" % src

      if os.path.isdir(dst):
        dir = dst
        dst = os.path.join(dst, os.path.basename(src))
      else:
        dir = os.path.dirname(dst)

      if not self.force and not newer(src, dst):
        return dst, 0

      if os.path.basename(dst) == os.path.basename(src):
        log.info("%s %s -> %s", name, src, dir)
      else:
        log.info("%s %s -> %s", name, src, dst)

      if self.dry_run:
        return (dst, 1)
      else:
        try:
          fsrc = open(src, 'rb')
        except os.error, (errno, errstr):
          raise DistutilsFileError, \
              "could not open '%s': %s" % (src, errstr)

        if os.path.exists(dst):
          try:
            os.unlink(dst)
          except os.error, (errno, errstr):
            raise DistutilsFileError, \
                "could not delete '%s': %s" % (dst, errstr)

        try:
          fdst = open(dst, 'wb')
        except os.error, (errno, errstr):
          raise DistutilsFileError, \
              "could not create '%s': %s" % (dst, errstr)

        try:
          fdst.write(actor(fsrc.read()))
        finally:
          fsrc.close()
          fdst.close()

        if preserve_mode or preserve_times:
          st = os.stat(src)

          if preserve_times:
            os.utime(dst, (st[ST_ATIME], st[ST_MTIME]))
          if preserve_mode:
            os.chmod(dst, S_IMODE(st[ST_MODE]))

        return (dst, 1)
    else:
      return Command.copy_file(self, src, dst, preserve_mode, preserve_times,
                               link, level)

doc_option = [('build-doc', None, 'build directory for documentation')]

class build(_build):

  user_options = _build.user_options + doc_option

  def initialize_options(self):
    _build.initialize_options(self)
    self.build_doc = None

  def finalize_options(self):
    _build.finalize_options(self)
    if self.build_doc is None:
      self.build_doc = "%s/doc" % self.build_base

  def get_sub_commands(self):
    return _build.get_sub_commands(self) + ["build_doc"]

class build_doc(Command):

  user_options = doc_option

  def initialize_options(self):
    self.build_doc = None

  def finalize_options(self):
    self.set_undefined_options('build', ('build_doc', 'build_doc'))

  def run(self):
    try:
      from epydoc.docbuilder import build_doc_index
      from epydoc.docwriter.html import HTMLWriter
    except ImportError, e:
      log.warn('%s -- skipping build_doc', e)
      return

    names = ["qpid.messaging"]
    doc_index = build_doc_index(names, True, True)
    html_writer = HTMLWriter(doc_index, show_private=False)
    self.mkpath(self.build_doc)
    log.info('epydoc %s to %s' % (", ".join(names), self.build_doc))
    html_writer.write(self.build_doc)

class clean(_clean):

  user_options = _clean.user_options + doc_option

  def initialize_options(self):
    _clean.initialize_options(self)
    self.build_doc = None

  def finalize_options(self):
    _clean.finalize_options(self)
    self.set_undefined_options('build', ('build_doc', 'build_doc'))

  def run(self):
    if self.all:
      if os.path.exists(self.build_doc):
        remove_tree(self.build_doc, dry_run=self.dry_run)
      else:
        log.debug("%s doesn't exist -- can't clean it", self.build_doc)
    _clean.run(self)

if MAJOR <= 2 and MINOR <= 3:
  from glob import glob
  from distutils.util import convert_path
  class distclass(Distribution):

    def __init__(self, *args, **kwargs):
      self.package_data = None
      Distribution.__init__(self, *args, **kwargs)
else:
  distclass = Distribution

ann = re.compile(r"([ \t]*)@([_a-zA-Z][_a-zA-Z0-9]*)([ \t\n\r]+def[ \t]+)([_a-zA-Z][_a-zA-Z0-9]*)")
line = re.compile(r"\n([ \t]*)[^ \t\n#]+")

class build_py(preprocessor, _build_py):

  if MAJOR <= 2 and MINOR <= 3:
    def initialize_options(self):
      _build_py.initialize_options(self)
      self.package_data = None

    def finalize_options(self):
      _build_py.finalize_options(self)
      self.package_data = self.distribution.package_data
      self.data_files = self.get_data_files()

    def get_data_files (self):
      data = []
      if not self.packages:
        return data
      for package in self.packages:
        # Locate package source directory
        src_dir = self.get_package_dir(package)

        # Compute package build directory
        build_dir = os.path.join(*([self.build_lib] + package.split('.')))

        # Length of path to strip from found files
        plen = 0
        if src_dir:
          plen = len(src_dir)+1

        # Strip directory from globbed filenames
        filenames = [file[plen:]
                     for file in self.find_data_files(package, src_dir)]
        data.append((package, src_dir, build_dir, filenames))
      return data

    def find_data_files (self, package, src_dir):
      globs = (self.package_data.get('', [])
               + self.package_data.get(package, []))
      files = []
      for pattern in globs:
        # Each pattern has to be converted to a platform-specific path
        filelist = glob(os.path.join(src_dir, convert_path(pattern)))
        # Files that match more than one pattern are only added once
        files.extend([fn for fn in filelist if fn not in files])
      return files

    def build_package_data (self):
      lastdir = None
      for package, src_dir, build_dir, filenames in self.data_files:
        for filename in filenames:
          target = os.path.join(build_dir, filename)
          self.mkpath(os.path.dirname(target))
          self.copy_file(os.path.join(src_dir, filename), target,
                         preserve_mode=False)

    def build_packages(self):
      _build_py.build_packages(self)
      self.build_package_data()

  # end if MAJOR <= 2 and MINOR <= 3

  def backport(self, input):
    output = ""
    pos = 0
    while True:
      m = ann.search(input, pos)
      if m:
        indent, decorator, idef, function = m.groups()
        output += input[pos:m.start()]
        output += "%s#@%s%s%s" % (indent, decorator, idef, function)
        pos = m.end()

        subst = "\n%s%s = %s(%s)\n" % (indent, function, decorator, function)
        npos = pos
        while True:
          n = line.search(input, npos)
          if not n:
            input += subst
            break
          if len(n.group(1)) <= len(indent):
            idx = n.start()
            input = input[:idx] + subst + input[idx:]
            break
          npos = n.end()
      else:
        break

    output += input[pos:]
    return output

  def actor(self, src, dst):
    base, ext = os.path.splitext(src)
    if ext == ".py" and MAJOR <= 2 and MINOR <= 3:
      return "backporting", self.backport
    else:
      return None, None

def pclfile(xmlfile):
  return "%s.pcl" % os.path.splitext(xmlfile)[0]

class install_lib(_install_lib):

  def get_outputs(self):
    outputs = _install_lib.get_outputs(self)
    extra = []
    for of in outputs:
      if os.path.basename(of) == "amqp-0-10-qpid-errata-stripped.xml":
        extra.append(pclfile(of))
    return outputs + extra

  def install(self):
    outfiles = _install_lib.install(self)
    extra = []
    for of in outfiles:
      if os.path.basename(of) == "amqp-0-10-qpid-errata-stripped.xml":
        tgt = pclfile(of)
        if self.force or newer(of, tgt):
          log.info("caching %s to %s" % (of, os.path.basename(tgt)))
          if not self.dry_run:
            from qpid.ops import load_types
            load_types(of)
        extra.append(tgt)
    return outfiles + extra

scripts = ["qpid-python-test"]

if platform.system() == "Windows":
  scripts.append("qpid-python-test.bat")
  
setup(name="qpid-python",
      version="1.36.0",
      author="Apache Qpid",
      author_email="users@qpid.apache.org",
      packages=["mllib", "qpid", "qpid.messaging", "qpid.tests",
                "qpid.tests.messaging", "qpid.saslmech", "qpid.tests.saslmech",
                "qpid_tests", "qpid_tests.broker_1_0", "qpid_tests.broker_0_10",
                "qpid_tests.broker_0_9", "qpid_tests.broker_0_8"],
      package_data={"qpid": ["specs/*.dtd", "specs/*.xml"]},
      scripts=scripts,
      url="http://qpid.apache.org/",
      license="Apache Software License",
      description="Python client implementation and AMQP conformance tests for Apache Qpid",
      cmdclass={"build": build,
                "build_py": build_py,
                "build_doc": build_doc,
                "clean": clean,
                "install_lib": install_lib},
      distclass=distclass)
