#!/usr/bin/env python3
# encoding: utf-8

# Unit tests for decopy
# Copyright (C) 2018 Maximiliano Curia <maxy@debian.org>
#
# License: ISC
#  Permission to use, copy, modify, and/or distribute this software for any
#  purpose with or without fee is hereby granted, provided that the above
#  copyright notice and this permission notice appear in all copies.
#  .
#  THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
#  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
#  AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
#  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
#  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
#  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
#  PERFORMANCE OF THIS SOFTWARE.

import glob
import json
import time
import sys

try:
    from tqdm import tqdm
except ImportError:
    def tqdm(*a, **kw):
        if a:
            return a[0]
        return kw.get('iterable', None)

from decopy import matchers


class SpeedCheck:

    def run(self):
        self.benchmark_licenses_res()
        self.benchmark_clean_comments()
        self.benchmark_copyright()
        self.benchmark_resubs()
        return 0

    def load_all_licenses(self):
        texts = []
        for filename in glob.glob('tests/testdata/licenses/*.json'):
            with open(filename) as file_:
                license_ = json.load(file_)
            for key in ('licenseText', 'standardLicenseHeader',
                        'licenseExceptionText'):
                if key not in license_:
                    continue
                texts.append(license_[key])
        return texts

    def benchmark_licenses_res(self):

        texts = self.load_all_licenses()
        times = []

        for i, pattern in tqdm(enumerate(matchers.COMPILED_RES),
                               desc='Timing license res',
                               total=len(matchers.COMPILED_RES),
                               dynamic_ncols=True):
            start = time.time()
            for text in texts:
                pattern.search(text)
            elapsed = time.time() - start
            times.append((elapsed, i))

        base, amount = 0, 0
        interesting = times[base:base + amount]
        if interesting:
            print("Sum of current selection: ",
                  sum(elapsed for elapsed, _ in interesting))
        times.sort()

        for elapsed, i in [times[0]] + interesting + times[-5:]:
            license_re = matchers.LICENSES_RES[i]
            print("Time for {} ({}): {}\n"
                  "{}".format(i, license_re.license, elapsed, license_re.re))

    def benchmark_resubs(self):

        texts = self.load_all_licenses()
        times = []
        resubs = (matchers.ARTISTIC_SUBS
                  + matchers.BSD_SUBS
                  + matchers.CC_BY_SUBS
                  + matchers.CECILL_SUBS
                  + matchers.CNRI_SUBS
                  + matchers.EFL_SUBS
                  + matchers.GNU_VERSION_SUBS
                  + matchers.GNU_EXCEPTION_SUBS
                  + matchers.GFDL_SUBS
                  + matchers.LPPL_SUBS
                  + matchers.MIT_SUBS
                  + matchers.ZPL_SUBS
                  )

        for i, resub in tqdm(enumerate(resubs),
                             desc='Timing resubs',
                             total=len(resubs),
                             dynamic_ncols=True):
            start = time.time()
            for text in texts:
                resub.pattern.subn(resub.repl, text, 1)
            elapsed = time.time() - start
            times.append((elapsed, i))

        base, amount = 0, 0
        interesting = times[base:base + amount]
        if interesting:
            print("Sum of current selection: ",
                  sum(elapsed for elapsed, _ in interesting))
        times.sort()

        for elapsed, i in [times[0]] + interesting + times[-5:]:
            resub = resubs[i]
            print("Time for {} (repl: {}): {}".format(i, resub.repl, elapsed))

    def benchmark_clean_comments(self):

        texts = self.load_all_licenses()
        times = []

        for i, sub in tqdm(enumerate(matchers.COMMENTS_SUBS),
                           desc='Timing comment res',
                           total=len(matchers.COMMENTS_SUBS),
                           dynamic_ncols=True):
            start = time.time()
            for text in texts:
                sub.pattern.sub(sub.repl, text)
            elapsed = time.time() - start
            times.append((elapsed, i))

        base, amount = 0, 0
        interesting = times[base:base + amount]
        if interesting:
            print("Sum of current selection: ",
                  sum(elapsed for elapsed, _ in interesting))
        times.sort()

        for elapsed, i in [times[0]] + interesting + times[-5:]:
            print("Time for {} : {}".format(i, elapsed))

    def benchmark_copyright(self):

        texts = self.load_all_licenses()
        times = []

        patterns = (matchers.COPYRIGHT_PRE_IGNORE_RES
                    + matchers.COPYRIGHT_POST_IGNORE_RES
                    + (matchers.COPYRIGHT_PRE_INDICATOR_RE,
                       matchers.COPYRIGHT_INDICATOR_RE))

        for i, pattern in tqdm(enumerate(patterns),
                               desc='Timing copyright res',
                               total=len(patterns),
                               dynamic_ncols=True):
            start = time.time()
            for text in texts:
                pattern.findall(text)
            elapsed = time.time() - start
            times.append((elapsed, i))

        base, amount = 0, 0
        # len(matchers.COPYRIGHT_PRE_IGNORE_RES) + 1, \
        #     len(matchers.COPYRIGHT_POST_IGNORE_RES)
        interesting = times[base:base + amount]
        if interesting:
            print("Sum of current selection: ",
                  sum(elapsed for elapsed, _ in interesting))
        times.sort()

        for elapsed, i in [times[0]] + interesting + times[-5:]:
            print("Time for {} : {}".format(i, elapsed))


if __name__ == '__main__':
    check = SpeedCheck()
    sys.exit(check.run())
