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

"""
A script for timing/profiling the Markdown conversion of an artifact discussion thread.

Example usage:

(env-allura)root@h1v1024:/var/local/allura/Allura(master)$ time paster script production.ini allura/scripts/md_perf.py -- --converter=forge
      Conversion Time (s)  Text Size Post._id
   1 0.021863937377929688         20 7d3ce86bb2c3afaee21f28547ed542d0c8c483b8
   2 0.002238035202026367         12 96b1283c6db619cd66ee092551758dc1ad5b958f
   3 0.001832962036132812          9 42c44cd72815d29069378353745bef953bdb2b98
   4 0.011796951293945312        901 cadbea52291c58bb190597c1df94527369b405fa
   5 0.143218040466308594      11018 362bee7ef1ba4e062712bda22cb96ae9fe459b95
   6 0.029596090316772461       1481 46b78785b849f55d24cf32ee1f4e4c916cb7a6fe
   7 0.045151948928833008       4144 4e2f62188080baba9b88c045ba1f7c26903bfcf9
   8 0.637056827545166016      14553 51c87f2b1d55c08147bb2353e20361236232b432
   9 4.510329008102416992      23016 f298ad88584f3dc9b5c37ffde61391bf03d5bae6
  10 3.614714860916137695      23016 8775a230b19c231daa1608bb4cea1e17aab54550
  11 0.393079042434692383      19386 ed79e0d2f89366043a007e0837e98945453508c9
  12 0.000739097595214844      43659 56ac2437ec1bd886a03d23e45aa1c947729760ec
  13 0.258469104766845703       8520 57152cefe0424b7fc9dff7ab4d21a6ef6e90bf82
  14 0.264052867889404297       8518 6788b13c90c9719ba46196a0a773f4c228df9f2a
  15 0.995774984359741211      14553 3f5cce06d2400bcd56d7b90d12c569935f0099a4
Total time: 10.930670023

real    0m14.256s
user    0m12.749s
sys     0m1.112s

"""

import argparse
import cProfile
import re
import sys
import time

from mock import patch

try:
    import re2
    re2.set_fallback_notification(re2.FALLBACK_WARNING)
    RE2_INSTALLED = True
except ImportError:
    RE2_INSTALLED = False

from pylons import app_globals as g

MAX_OUTPUT = 99999
DUMMYTEXT = None


def get_artifact():
    from forgeblog import model as BM
    return BM.BlogPost.query.get(
            slug='2013/09/watch-breaking-bad-season-5-episode-16-felina-live-streaming')


def main(opts):
    import markdown
    if opts.re2 and RE2_INSTALLED:
        markdown.inlinepatterns.re = re2
    converters = {
        'markdown': lambda: markdown.Markdown(),
        'markdown_safe': lambda: markdown.Markdown(safe_mode=True),
        'markdown_escape': lambda: markdown.Markdown(safe_mode='escape'),
        'forge': lambda: g.markdown,
        }
    md = converters[opts.converter]()
    artifact = get_artifact()
    return render(artifact, md, opts)


def render(artifact, md, opts):
    start = begin = time.time()
    print "%4s %20s %10s %s" % ('', 'Conversion Time (s)', 'Text Size', 'Post._id')
    for i, p in enumerate(artifact.discussion_thread.posts):
        text = DUMMYTEXT or p.text
        if opts.n and i + 1 not in opts.n:
            print 'Skipping post %s' % str(i + 1)
            continue
        if opts.profile:
            print 'Profiling post %s' % str(i + 1)
            cProfile.runctx('output = md.convert(text)', globals(), locals())
        else:
            output = md.convert(text)
        elapsed = time.time() - start
        print "%4s %1.18f %10s %s" % (i + 1, elapsed, len(text), p._id)
        if opts.output:
            print 'Input:', text[:min(300, len(text))]
            print 'Output:', output[:min(MAX_OUTPUT, len(output))]
        start = time.time()
    print "Total time:", start - begin
    return output


def parse_options():
    parser = argparse.ArgumentParser()
    parser.add_argument('--converter', default='markdown')
    parser.add_argument('--profile', action='store_true', help='Run profiler and output timings')
    parser.add_argument('--output', action='store_true', help='Print result of markdown conversion')
    parser.add_argument('--re2', action='store_true', help='Run with re2 instead of re')
    parser.add_argument('--compare', action='store_true', help='Run with re and re2, and compare results')
    parser.add_argument('-n', '--n', nargs='+', type=int, help='Only convert nth post(s) in thread')
    return parser.parse_args()


if __name__ == '__main__':
    opts = parse_options()
    out1 = main(opts)
    if opts.compare:
        opts.re2 = not opts.re2
        out2 = main(opts)
        print 're/re2 outputs match: ', out1 == out2
