#!/usr/bin/env python
#
# Copyright (c) Vicent Marti. All rights reserved.
#
# This file is part of clar, distributed under the ISC license.
# For full terms see the included COPYING file.
#

from __future__ import with_statement
from string import Template
import re, fnmatch, os, codecs, pickle

class Module(object):
    class Template(object):
        def __init__(self, module):
            self.module = module

        def _render_callback(self, cb):
            if not cb:
                return '    { NULL, NULL }'
            return '    { "%s", &%s }' % (cb['short_name'], cb['symbol'])

    class DeclarationTemplate(Template):
        def render(self):
            out = "\n".join("extern %s;" % cb['declaration'] for cb in self.module.callbacks) + "\n"

            if self.module.initialize:
                out += "extern %s;\n" % self.module.initialize['declaration']

            if self.module.cleanup:
                out += "extern %s;\n" % self.module.cleanup['declaration']

            return out

    class CallbacksTemplate(Template):
        def render(self):
            out = "static const struct clar_func _clar_cb_%s[] = {\n" % self.module.name
            out += ",\n".join(self._render_callback(cb) for cb in self.module.callbacks)
            out += "\n};\n"
            return out

    class InfoTemplate(Template):
        def render(self):
            return Template(
            r"""
    {
        "${clean_name}",
    ${initialize},
    ${cleanup},
        ${cb_ptr}, ${cb_count}, ${enabled}
    }"""
            ).substitute(
                clean_name = self.module.clean_name(),
                initialize = self._render_callback(self.module.initialize),
                cleanup = self._render_callback(self.module.cleanup),
                cb_ptr = "_clar_cb_%s" % self.module.name,
                cb_count = len(self.module.callbacks),
                enabled = int(self.module.enabled)
            )

    def __init__(self, name):
        self.name = name

        self.mtime = 0
        self.enabled = True
        self.modified = False

    def clean_name(self):
        return self.name.replace("_", "::")

    def _skip_comments(self, text):
        SKIP_COMMENTS_REGEX = re.compile(
            r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
            re.DOTALL | re.MULTILINE)

        def _replacer(match):
            s = match.group(0)
            return "" if s.startswith('/') else s

        return re.sub(SKIP_COMMENTS_REGEX, _replacer, text)

    def parse(self, contents):
        TEST_FUNC_REGEX = r"^(void\s+(test_%s__(\w+))\s*\(\s*void\s*\))\s*\{"

        contents = self._skip_comments(contents)
        regex = re.compile(TEST_FUNC_REGEX % self.name, re.MULTILINE)

        self.callbacks = []
        self.initialize = None
        self.cleanup = None

        for (declaration, symbol, short_name) in regex.findall(contents):
            data = {
                "short_name" : short_name,
                "declaration" : declaration,
                "symbol" : symbol
            }

            if short_name == 'initialize':
                self.initialize = data
            elif short_name == 'cleanup':
                self.cleanup = data
            else:
                self.callbacks.append(data)

        return self.callbacks != []

    def refresh(self, path):
        self.modified = False

        try:
            st = os.stat(path)

            # Not modified
            if st.st_mtime == self.mtime:
                return True

            self.modified = True
            self.mtime = st.st_mtime

            with codecs.open(path, encoding='utf-8') as fp:
                raw_content = fp.read()

        except IOError:
            return False

        return self.parse(raw_content)

class TestSuite(object):

    def __init__(self, path):
        self.path = path

    def should_generate(self, path):
        if not os.path.isfile(path):
            return True

        if any(module.modified for module in self.modules.values()):
            return True

        return False

    def find_modules(self):
        modules = []
        for root, _, files in os.walk(self.path):
            module_root = root[len(self.path):]
            module_root = [c for c in module_root.split(os.sep) if c]

            tests_in_module = fnmatch.filter(files, "*.c")

            for test_file in tests_in_module:
                full_path = os.path.join(root, test_file)
                module_name = "_".join(module_root + [test_file[:-2]]).replace("-", "_")

                modules.append((full_path, module_name))

        return modules

    def load_cache(self):
        path = os.path.join(self.path, '.clarcache')
        cache = {}

        try:
            fp = open(path, 'rb')
            cache = pickle.load(fp)
            fp.close()
        except (IOError, ValueError):
            pass

        return cache

    def save_cache(self):
        path = os.path.join(self.path, '.clarcache')
        with open(path, 'wb') as cache:
            pickle.dump(self.modules, cache)

    def load(self, force = False):
        module_data = self.find_modules()
        self.modules = {} if force else self.load_cache()

        for path, name in module_data:
            if name not in self.modules:
                self.modules[name] = Module(name)

            if not self.modules[name].refresh(path):
                del self.modules[name]

    def disable(self, excluded):
        for exclude in excluded:
            for module in self.modules.values():
                name = module.clean_name()
                if name.startswith(exclude):
                    module.enabled = False
                    module.modified = True

    def suite_count(self):
        return len(self.modules)

    def callback_count(self):
        return sum(len(module.callbacks) for module in self.modules.values())

    def write(self):
        output = os.path.join(self.path, 'clar.suite')

        if not self.should_generate(output):
            return False

        with open(output, 'w') as data:
            for module in self.modules.values():
                t = Module.DeclarationTemplate(module)
                data.write(t.render())

            for module in self.modules.values():
                t = Module.CallbacksTemplate(module)
                data.write(t.render())

            suites = "static struct clar_suite _clar_suites[] = {" + ','.join(
                Module.InfoTemplate(module).render() for module in sorted(self.modules.values(), key=lambda module: module.name)
            ) + "\n};\n"

            data.write(suites)

            data.write("static const size_t _clar_suite_count = %d;\n" % self.suite_count())
            data.write("static const size_t _clar_callback_count = %d;\n" % self.callback_count())

        self.save_cache()
        return True

if __name__ == '__main__':
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option('-f', '--force', action="store_true", dest='force', default=False)
    parser.add_option('-x', '--exclude', dest='excluded', action='append', default=[])

    options, args = parser.parse_args()

    for path in args or ['.']:
        suite = TestSuite(path)
        suite.load(options.force)
        suite.disable(options.excluded)
        if suite.write():
            print("Written `clar.suite` (%d tests in %d suites)" % (suite.callback_count(), suite.suite_count()))

