#!/usr/bin/env python

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

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
import argparse
import json
import logging
import random
import string
import csv

from tg import tmpl_context as c
from testfixtures import LogCapture
from mock import patch
from ming.odm import ThreadLocalODMSession

from allura import model as M
from allura.lib.helpers import push_config
from allura.tests import TestController
from allura.tests.decorators import patch_middleware_config

from forgewiki import model as WM
from io import open
from six.moves import range


def parse_args():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawTextHelpFormatter,
        description='Count number of expensive calls (mongo, markdown, etc) for a standard page.\n'
                    'Currently its a _discuss URL with a few posts on it.  This exercises core logic\n'
                    '(project & tool lookup, security, discussion thread, main template, etc) but\n'
                    'intentionally avoids most tool-specific code.')
    parser.add_argument('--verbose', '-v', action='store_true', default=False,
                        help='Show call details.  Note that Timers with debug_each_call=False (like ming\'s Cursor.next) are not displayed in verbose mode (but they are counted).')
    parser.add_argument('--debug-html', action='store_true', default=False,
                        help='Save HTML responses as local files')
    parser.add_argument(
        '--data-file', default='call_counts.csv', type=argparse.FileType('a'),
        help='CSV file that is appended to')
    parser.add_argument('--id', default='',
                        help='An identifier for this run.  Examples:\n'
                             '`git rev-parse --short HEAD` for current hash\n'
                             '`git log -1 --oneline` for hash + message')
    return parser.parse_args()


def main(args):
    test = TestController()
    setup(test)

    url = generate_wiki_thread(test)
    # make sure ODM sessions won't get re-used
    ThreadLocalODMSession.close_all()

    counts = count_page(test, url, verbose=args.verbose,
                        debug_html=args.debug_html)
    print(json.dumps(counts))
    write_csv(counts, args.id, args.data_file)
    test.tearDown()


def setup(test):
    # includes setting up mim
    with patch_middleware_config({'stats.sample_rate': 1,
                                  'stats.debug_line_length': 1000,
                                  }), \
            patch('timermiddleware.log.isEnabledFor', return_value=True):  # can't set this via logging configuration since setUp() will load a logging config and then start using it before we have a good place to tweak it
        test.setUp()

    tmw_log = logging.getLogger('timermiddleware')
    tmw_log.disabled = 0  # gets disabled when .ini file is loaded; dumb.
    tmw_log.setLevel(logging.DEBUG)


def generate_wiki_thread(test):
    # automagically instantiate the app
    test.app.get('/wiki/')

    project = M.Project.query.get(shortname='test')
    app = project.app_instance('wiki')

    page = WM.Page.query.get(app_config_id=app.config._id, title='Home')
    thread = page.discussion_thread
    # create a few posts by a few users
    with push_config(c, user=M.User.query.get(username='test-admin'),
                     app=app,
                     project=project):
        thread.add_post(text='This is very helpful')
        thread.add_post(text="But it's not **super** helpful")
        with push_config(c, user=M.User.query.get(username='test-user')):
            thread.add_post(text='I disagree')
        with push_config(c, user=M.User.query.get(username='test-user-1')):
            thread.add_post(text='But what about foo?')

    ThreadLocalODMSession.flush_all()

    url = '/p/test/wiki/_discuss/thread/{}/'.format(thread._id)
    return url


def count_page(test, url, verbose=False, debug_html=False):

    with LogCapture('stats') as stats, LogCapture('timermiddleware') as calls:
        resp = test.app.get(url, extra_environ=dict(username=str('*anonymous')))
        print(url, resp.status)
        if debug_html:
            debug_filename = 'call-{}.html'.format(''.join([random.choice(string.ascii_letters + string.digits)
                                                   for n in range(10)]))
            with open(debug_filename, 'w') as out:
                out.write(resp.body)
            print(debug_filename)

    if verbose:
        for r in calls.records:
            print(r.getMessage())

    assert len(stats.records) == 1
    timings = json.loads(stats.records[0].getMessage())
    # total is always 1, which is misleading
    del timings['call_counts']['total']
    return timings['call_counts']


def write_csv(counts, id, data_file):
    cols = sorted(counts.keys())
    row = counts
    if id:
        cols = ['id'] + cols
        row = dict(counts, id=id)
    csv_out = csv.DictWriter(data_file, cols)
    if data_file.tell() == 0:
        csv_out.writeheader()
    csv_out.writerow(row)
    data_file.close()


if __name__ == '__main__':
    main(parse_args())
