#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Configures system-specifc settings and runs `make` to build sharedlibs on the
current system.
"""

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import os
from os.path import join as pjoin
import sys
import subprocess
import time
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

if 'CONDA_PREFIX' in os.environ:
    PREFIX = os.environ['CONDA_PREFIX']
else:
    PREFIX = sys.prefix


def build_libtomopy():
    """Build libtomopy shared library for the current system.

    This does the following steps:
      1. write `Mk.config` for current os
      2. run `make -j4` for the the current os
    """
    if sys.platform.lower().startswith('win'):
        makefile = 'Makefile.windows'
        conf = config_windows()
    elif sys.platform == 'darwin':
        makefile = 'Makefile.darwin'
        conf = config_macosx()
    else:
        makefile = 'Makefile.linux'
        conf = config_linux()
    logger.info("Config output:\n" + conf)
    with open('Mk.config', 'w') as fout:
        fout.write(conf)
    subprocess.check_call(('make', '-j4', '-f', makefile))


class Config:
    """A string formatter for the Makefile"""
    def __init__(self):
        self.compilerdir = 'gcc'
        self.sharedlib = 'libtike'
        self.arch_target = ''
        self.conda_compat = ''
        self.includes = [pjoin(os.path.dirname(os.getcwd()), 'include')]
        self.linklibs = ['%s' % pjoin(PREFIX, 'lib')]
        # anaconda compat?
        if 'conda' in sys.version:
            compat = pjoin(PREFIX, 'compiler_compat')
            if os.path.exists(compat) and os.path.isdir(compat):
                self.conda_compat = '-B %s' % compat
        if 'GCC' in os.environ:
            self.compilerdir = os.environ["GCC"]
        # includes
        top_include = pjoin(PREFIX, 'include')
        if os.path.exists(top_include):
            includes = [top_include]
            for fname in os.listdir(top_include):
                tdir = pjoin(top_include, fname)
                if os.path.isdir(tdir) and 'python' in fname:
                    includes.append(tdir)
            self.includes += includes

    def format(self):
        """Return the formatted string, replacing Windows \\ with Unix /."""
        include = ' '.join(['-I%s' % s for s in self.includes])
        linklib = ' '.join(['-L%s' % s for s in self.linklibs])
        buff = ['## generated by build.py  %s' % time.ctime(),
                'COMPILER_DIR  = %s' % self.compilerdir,
                'SHAREDLIB     = %s' % self.sharedlib,
                'ARCH_TARGET   = %s' % self.arch_target,
                'LINK_LIB      = %s' % linklib,
                'INCLUDE       = %s' % include,
                'CONDA_COMPAT  = %s' % self.conda_compat,
                '####', '']
        return '\n'.join(buff).replace('\\', '/')


def config_linux():
    """config for Linux"""
    logger.info("Config for Linux")
    config = Config()
    config.sharedlib += '.so'
    return config.format()


def config_macosx():
    """config for MacOSX"""
    logger.info("Config for MacOS")
    config = Config()
    config.sharedlib += '.dylib'
    config.arch_target = '-arch x86_64'
    return config.format()


def config_windows():
    """config for Windows"""
    logger.info("Config for Windows")
    config = Config()
    compilerdir = None
    if 'conda' in sys.version:
        # Look for GCC in the conda directory
        mingw_path = pjoin(PREFIX, 'MinGW', 'bin')
        mingw_gcc = pjoin(mingw_path, 'gcc.exe')
        if os.path.exists(mingw_gcc):
            logger.info("COMPILER_DIR is {}".format(mingw_gcc))
            compilerdir = mingw_path
        else:
            logger.warn("Compiler not found at {}".format(mingw_gcc))
    if compilerdir is None:
        for pdir in os.environ['PATH'].split(';'):
            gcc = pjoin(pdir, 'gcc.exe')
            if os.path.exists(gcc):
                compilerdir = pdir
                logger.info("COMPILER_DIR is {}".format(pdir))
                break
    if compilerdir is not None:
        config.compilerdir = compilerdir
    config.sharedlib += '.dll'
    config.includes += [pjoin(PREFIX, 'Library', 'include')]
    config.linklibs = [PREFIX,
                       pjoin(PREFIX, 'Library', 'bin'),
                       os.path.dirname(os.path.dirname(PREFIX)),
                       "C:/Windows/System32",
                       ]
    return config.format()


if __name__ == '__main__':
    curpath = os.getcwd()
    os.chdir('config')
    build_libtomopy()
    os.chdir(curpath)
