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

from distutils.core import setup, Extension
from distutils.command.build import build as _build
from distutils.command.clean import clean as _clean
from distutils.cmd import Command as _Command
from distutils.dep_util import newer_group
import distutils.ccompiler
import os
import glob
import platform
import re
import shutil
import subprocess
import sysconfig
import sys
import unittest

# Get a compiler object and and strings representing the compiler type and
# CFLAGS.
compiler = distutils.ccompiler.new_compiler()
cflags = sysconfig.get_config_var('CFLAGS')
compiler_type = distutils.ccompiler.get_default_compiler()

# There's no public way to get a string representing the compiler executable
# out of distutils, but the member variable has been in the same place for a
# long time, so violating encapsulation may be ok.
compiler_name = " ".join(compiler.compiler)
make_command = "make" # TODO portability

BASE_DIR        = os.path.abspath(os.path.join(os.pardir, os.pardir))
PARENT_DIR      = os.path.abspath(os.pardir)
CFC_SOURCE_DIR  = os.path.join(PARENT_DIR, 'src')
CFC_INCLUDE_DIR = os.path.join(PARENT_DIR, 'include')
COMMON_SOURCE_DIR    = os.path.join(PARENT_DIR, 'common')
CHARMONIZER_C        = os.path.join(COMMON_SOURCE_DIR, 'charmonizer.c')
CHARMONIZER_EXE_NAME = compiler.executable_filename('charmonizer')
CHARMONIZER_EXE_PATH = os.path.join(os.curdir, CHARMONIZER_EXE_NAME)
CHARMONY_H_PATH      = 'charmony.h'
LIBCFC_NAME          = 'libcfc.a' # TODO portability
LIBCFC_PATH          = os.path.abspath(os.path.join(os.curdir, LIBCFC_NAME))

c_filepaths = [os.path.join('src', 'cfc', '_cfc.c')]
paths_to_clean = [
    CHARMONIZER_EXE_PATH,
    CHARMONY_H_PATH,
    '_charm*',
]

def _quotify(text):
    text = text.replace('\\', '\\\\')
    text = text.replace('"', '\\"')
    return '"' + text + '"'

class charmony(_Command):
    description = "Build and run charmonizer"
    user_options = []
    def initialize_options(self):
        pass
    def finalize_options(self):
        pass
    def run(self):
        # Compile charmonizer.
        if newer_group([CHARMONIZER_C], CHARMONIZER_EXE_PATH):
            command = [compiler_name]
            if compiler_type == 'msvc':
                command.append('/Fe' + CHARMONIZER_EXE_PATH)
            else:
                command.extend(['-o', CHARMONIZER_EXE_PATH])
            command.append(CHARMONIZER_C)
            print(" ".join(command))
            subprocess.check_call(command)

        # Run charmonizer.
        if newer_group([CHARMONIZER_EXE_PATH], CHARMONY_H_PATH):
            command = [
                CHARMONIZER_EXE_PATH,
                '--cc=' + _quotify(compiler_name),
                '--enable-c',
                '--host=python',
                '--enable-makefile',
                '--',
                cflags
            ]
            if 'CHARM_VALGRIND' in os.environ:
                command[0:0] = "valgrind", "--leak-check=yes";
            print(" ".join(command))
            subprocess.check_call(command)

class libcfc(_Command):
    description = "Build CFC as a static archive."
    user_options = []
    def initialize_options(self):
        pass
    def finalize_options(self):
        pass
    def run(self):
        self.run_command('charmony')
        subprocess.check_call([make_command, '-j', 'static'])
        # Touch Python binding file if the library has changed.
        cfc_c = os.path.join('src', 'cfc', '_cfc.c')
        if newer_group(['libcfc.a'], cfc_c):
            os.utime(cfc_c, None)

class my_clean(_clean):
    def run(self):
        _clean.run(self)
        if os.path.isfile("Makefile"):
            subprocess.check_call([make_command, 'distclean'])
        for elem in paths_to_clean:
            for path in glob.glob(elem):
                print("removing " + path)
                if os.path.isdir(path):
                    shutil.rmtree(path)
                else:
                    os.unlink(path)

class my_build(_build):
    def run(self):
        self.run_command('charmony')
        self.run_command('libcfc')
        _build.run(self)

class test(_Command):
    description = "Run unit tests."
    user_options = []
    def initialize_options(self):
        pass
    def finalize_options(self):
        pass
    def ext_build_dir(self):
        """Returns the build directory for compiled extensions"""
        pattern = "lib.{platform}-{version[0]}.{version[1]}"
        dirname = pattern.format(platform=sysconfig.get_platform(),
                                 version=sys.version_info)
        return os.path.join('build', dirname)

    def run(self):
        self.run_command('build')
        orig_sys_path = sys.path[:]
        sys.path.append(self.ext_build_dir())

        loader = unittest.TestLoader()
        tests = loader.discover("test")
        test_runner = unittest.runner.TextTestRunner()
        test_runner.run(tests)

        # restore sys.path
        sys.path = orig_sys_path

cfc_extension = Extension('cfc._cfc',
                          define_macros = [('CFCPYTHON', None)],
                          include_dirs = [
                              CFC_INCLUDE_DIR,
                              CFC_SOURCE_DIR,
                              os.curdir,
                          ],
                          extra_link_args = [LIBCFC_PATH],
                          sources = c_filepaths)

setup(name = 'clownfish-cfc',
      version = '0.4.0',
      description = 'Clownfish compiler',
      author = 'Apache Lucy Project',
      author_email = 'dev at lucy dot apache dot org',
      url = 'http://lucy.apache.org',
      packages = ['cfc',
                 ],
      cmdclass = {
          'build': my_build,
          'clean': my_clean,
          'charmony': charmony,
          'libcfc': libcfc,
          'test': test,
      },
      package_dir={'': 'src'},
      ext_modules = [cfc_extension])

