import os
import sys
import logging

import configparser
from .compiler import Compiler

# build options
GLOBAL_SECTION = 'global'
PROFILES = {
    'dev': {
        '.ts': ['ts_compile'],
        '.less': ['less_compile']
    },
    'dist': {
        '.html': ['html_compress'],
        '.js': ['js_compress'],
        '.css': ['css_compress'],
        '.ts': ['ts_compile', 'js_compress'],
        '.less': ['less_compile', 'css_compress']
    }
}


class Pipeline:
    def __init__(self, profile, config):
        self.config = PROFILES[profile]
        self.concat_files = config['concat']

        # try to use [profile] section config, then global section
        try:
            self.src_dir = config.get(profile, 'src_dir')
        except configparser.NoSectionError:
            self.src_dir = config.get(GLOBAL_SECTION, 'src_dir', fallback = 'src')

        try:
            self.dest_dir = config.get(profile, 'dest_dir')
        except configparser.NoSectionError:
            self.dest_dir = config.get(GLOBAL_SECTION, 'dest_dir', fallback = 'build')


        self.compiler = Compiler(self.src_dir, self.dest_dir)
        self.file_list = []

    def add(self, rawpath):
        self.file_list.append(rawpath)

    def run(self):
        for fpath in self.file_list:
            self.process(fpath)

    def process(self, rawpath):
        logging.info('Processing file: %s' % rawpath)

        # read file or concat multiple files
        if rawpath in self.concat_files:
            parts = self.concat_files[rawpath].strip().splitlines()
            content = b'\n'.join([open(os.path.join(self.src_dir, part), 'rb').read() for part in parts])
        else:
            content = open(os.path.join(self.src_dir, rawpath), 'rb').read()


        # continuously run tasks
        fpath = rawpath
        tasks = self.getTasks(rawpath)
        while tasks:
            task = tasks[0]
            tasks = tasks[1:]

            logging.info('Running task: %s' % task)
            try:
                content, fpath = getattr(self.compiler, task)(content, fpath)
            except:
                logging.error('Failed to process file: %s' % rawpath)
                logging.error(sys.exc_info()[1])

        # write file
        dpath = os.path.join(self.dest_dir, fpath)

        # make sure target directory exist
        dname = os.path.split(dpath)[0]
        if not os.path.isdir(dname):
            os.makedirs(dname, exist_ok=True)

        with open(dpath, 'wb') as f:
            f.write(content)


    def getTasks(self, fpath):

        ext = os.path.splitext(fpath)[1]
        try:
            tasks = self.config[ext]
        except KeyError:
            tasks = []

        return tasks
