# -*- coding: utf-8 -*-

#-------------------------------------------------------------------------
# Quality Program utilities
# --------------------------------------
#
# Copyright 2018
#
# Licensed 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.
#
#-------------------------------------------------------------------------

import os
import copy
import sys
import xml.sax
import xml.sax.handler
from log_parser import BatchResultParser, StatusCode

class TimeOfExecutionGroups() :
    def __init__(self):
        self.path = ""
        self.numberOfTests = 0
        self.timeOfExecution = 0

class TimeOfExecutionTests() :
    def __init__(self):
        self.path = ""
        self.timeOfExecution = 0

def sortKey (element ) :
    return int(element.timeOfExecution)

def sortKeyTimePerTest (element) :
    return int(int(element.timeOfExecution)/int(element.numberOfTests))

class XMLLogHandlerTests(xml.sax.handler.ContentHandler) :
    def __init__ (self):
        self.list = []
        self.element = TimeOfExecutionTests()
        self.testTime = False

    def startElement (self, name, attrs):
        if name == "TestCaseResult" :
            self.element.path = attrs.getValue("CasePath")
        if name == "Number" and "TestDuration" == attrs.getValue("Name") :
            self.testTime = True

    def characters(self, content) :
        if self.testTime :
            self.testTime = False
            self.element.timeOfExecution = content
            self.list.append(copy.deepcopy(self.element))

    def bottleneck (self, resultCount) :
        print("The biggest tests time of execution")
        print('%-4s%12s\t%12s' % ("Index", "Time", "Full name"))
        self.list.sort(key = sortKey, reverse = True)
        ndx = 1
        for test in self.list :
            print('%-4i%12i\t%12s' % (int(ndx), int(test.timeOfExecution), test.path))
            ndx+=1
            if int(ndx) > int(resultCount) :
                break

class XMLLogHandlerGroups(xml.sax.handler.ContentHandler) :
    def __init__ (self, testList) :
        self.list = []
        self.testList = testList
        self.element = TimeOfExecutionGroups()
        self.addIt = False

    def startElement (self, name, attrs) :
        self.element.numberOfTests = 0
        if name == "Number" :
            self.element.path = attrs.getValue("Name")
            if self.element.path == "dEQP-VK" :
                self.addIt = True
                self.element.numberOfTests = len(self.testList)
            else :
                for test in self.testList :
                    if test.path[:test.path.rfind(".")] in self.element.path :
                        self.addIt = True
                        self.element.numberOfTests += 1

    def characters(self, content) :
        if self.addIt :
            self.addIt = False
            self.element.timeOfExecution = content
            self.list.append(copy.deepcopy(self.element))

    def bottleneck (self, resultCount) :
        self.list.sort(key = sortKey, reverse = True)
        print("\nGroups Statistics")
        print("Total time of execution:\t", self.list[0].timeOfExecution)
        print("Number of executed tests:\t", self.list[0].numberOfTests)
        print("\nThe biggest total time of execution")
        print('%-4s%15s%15s\t%-30s' % ("Index", "Time", "Test count", "Full name"))
        ndx = 1
        for test in self.list :
            if test.path == "dEQP-VK" :
                continue
            print('%-4s%15s%15s\t%-30s' % (ndx, test.timeOfExecution, test.numberOfTests, test.path))
            ndx+=1
            if int(ndx) > int(resultCount) :
                break
        self.list.sort(key = sortKeyTimePerTest, reverse = True)
        print("\nThe biggest time of execution per test")
        print('%-4s%15s%15s%15s\t%-30s' % ("Index", "Time", "Test count", "\tAvg. test time", "Full name"))
        ndx = 1
        for test in self.list :
            if test.path == "dEQP-VK" :
                continue
            print('%-4s%15s%15s%15i\t%-30s' % (ndx, test.timeOfExecution, test.numberOfTests, int(test.timeOfExecution)/int(test.numberOfTests), test.path))
            ndx+=1
            if int(ndx) > int(resultCount) :
                break

class LogErrorHandler(xml.sax.handler.ErrorHandler) :
    def __init__ (self) :
        pass

    def error (self, err) :
        #print("error(%s)" % str(err))
        pass

    def fatalError (self, err) :
        #print("fatalError(%s)" % str(err))
        pass

    def warning (self, warn) :
        #print("warning(%s)" % str(warn))
        pass

def findFirstElementByName (nodes, name) :
    for node in nodes:
        if node.nodeName == name :
            return node
        chFound = findFirstElementByName(node.childNodes, name)
        if chFound != None :
            return chFound
    return None

def printTimes (inFile, resultCount) :
    #Test section
    parser = BatchResultParser()
    results = parser.parseFile(inFile)
    handler = XMLLogHandlerTests()
    errHandler = LogErrorHandler()
    for result in results :
        xml.sax.parseString(result.log, handler, errHandler)
    handler.bottleneck(resultCount)

    #Group section
    startRecordLines = False
    lines = ""
    f = open(inFile, 'rb')
    for line in f :
        if "#endTestsCasesTime" in line :
            break
        if startRecordLines :
            lines += line
        if "#beginTestsCasesTime" in line :
            startRecordLines = True
    f.close()
    handlerGroups = XMLLogHandlerGroups(handler.list)
    xml.sax.parseString(lines, handlerGroups, errHandler)
    handlerGroups.bottleneck(resultCount)

if __name__ == "__main__" :
    if len(sys.argv) != 3:
        print("%s: [test log] [count of result to display]" % sys.argv[0])
        print("example: python %s TestResults.qpa 10" % sys.argv[0])
        sys.exit(-1)
    printTimes(sys.argv[1], sys.argv[2])
