#!/opt/app/cacheDB/python/bin/python3
import cgitb
cgitb.enable()
import cgi
from vertica_getter import VerticaGetter

TABLE_OPEN = '<table id = LogPartsResult class="table table-striped table-bordered" cellspacing="0" width="100%">'
THEAD_OPEN = '<thead>'
TBODY_OPEN = '<tbody>'
ROW_OPEN = '<tr>'
COLUMN_OPEN = '<td>'
THEAD_ROW_OPEN = '<th>'
TABLE_CLOSE = '</table>'
ROW_CLOSE = '</tr>'
COLUMN_CLOSE = '</td>'
THEAD_CLOSE = '</thead>'
TBODY_CLOSE = '</tbody>'
THEAD_ROW_CLOSE = '</th>'

class ResultModel():
    """ A class to create model for the UI """

    def __init__(self):
        """ The default constructor"""
        pass

    def __init__(self,start_date,recordID,param_name,context_name,param_value,aggr_flag,exact_flag):
        """ The contructor takes 2 arguments at the minimum"""
        self.start_date = start_date
        self.recordID = recordID
        self.param_name = param_name
        self.context_name = context_name
        self.param_value = param_value
        self.aggr_flag = aggr_flag
        self.exact_flag = exact_flag

    def get_data(self):
        """ A method to get data from Vertica based on different conditions"""
        data_obj = VerticaGetter()
        if self.context_name == 'PARTS':
            # Get aggregated result
            if self.aggr_flag == 'true':
                param_list = [self.start_date,self.param_name,self.param_value]
                param_list = [str(elem) for elem in param_list]
                res = data_obj.get_log_parts_pattern_aggr(param_list)
            else:
                # Get records for a parameter matching a parameter value
                if self.param_value is not '' and self.param_name is not '':
                    param_list = [self.start_date,self.param_name,self.param_value]
                    param_list = [str(elem) for elem in param_list]
                    res = data_obj.get_log_parts_pattern_limit(param_list)
                # Get records for a parameter name on a given data, no parameter value
                if self.param_value is '' and self.param_name is not '' and self.recordID is '':
                    param_list = [self.start_date,self.param_name]
                    param_list = [str(elem) for elem in param_list]
                    res = data_obj.get_log_parts_param(param_list)
                # Get records for a single fileID/recordID when name and value are not selected
                if self.param_value is '' and self.recordID is not '':
                    #param_list = [self.start_date,self.recordID]
                    param_list = [self.recordID]
                    param_list = [str(elem) for elem in param_list]
                    res = data_obj.get_log_parts(param_list)
                # Get records matching a particular pattern for parameter value
                if self.recordID is '' and self.exact_flag is 'true':
                    param_list = [self.start_date,self.param_name,self.param_value]
                    param_list = [str(elem) for elem in param_list]
                    res = data_obj.get_log_parts_pattern(param_list)
        else:
            if self.param_value == '':
                param_list = [self.start_date,self.recordID]
                param_list = [str(elem) for elem in param_list]
                res = data_obj.get_log_parts(param_list)
            # Get records for a single fileID/recordID
            if self.param_name == '':
                param_list = [self.start_date,self.recordID]
                param_list = [str(elem) for elem in param_list]
                res = data_obj.get_log_parts(param_list)
            if self.recordID == '':
                param_list = [self.start_date,self.param_name,self.param_value]
                param_list = [str(elem) for elem in param_list]
                res = data_obj.get_log_parts_pattern(param_list)
        return res

    def format_default_result(self,db_res):
        """ Receives an object from the database and formats to an html table"""
        res_str =  []
        res_str.append(TABLE_OPEN)
        res_str.append(THEAD_OPEN)
        res_str.append(ROW_OPEN)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('File ID')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('Parameter Name')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('Parameter Value')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('UUID')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('Source')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(ROW_CLOSE)
        res_str.append(THEAD_CLOSE)
        res_str.append(TBODY_OPEN)
        for row in db_res:
            res_str.append(ROW_OPEN)
            for elem in row:
                res_str.append(COLUMN_OPEN)
                res_str.append(str(elem))  # do this gracefully
                res_str.append(COLUMN_CLOSE)
            res_str.append(ROW_CLOSE)
        res_str.append(TBODY_CLOSE)
        res_str.append(TABLE_CLOSE)
        return "".join(res_str)

    def format_aggr_result(self,db_res):
        """ Receives an object from the database and formats to an html table"""
        res_str =  []
        res_str.append(TABLE_OPEN)
        res_str.append(THEAD_OPEN)
        res_str.append(ROW_OPEN)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('Date')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('Count')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('Parameter Name')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('Parameter Value')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(THEAD_ROW_OPEN)
        res_str.append('Source')
        res_str.append(THEAD_ROW_CLOSE)
        res_str.append(ROW_CLOSE)
        res_str.append(THEAD_CLOSE)
        res_str.append(TBODY_OPEN)
        for row in db_res:
            res_str.append(ROW_OPEN)
            for elem in row:
                res_str.append(COLUMN_OPEN)
                res_str.append(str(elem))  # do this gracefully
                res_str.append(COLUMN_CLOSE)
            res_str.append(ROW_CLOSE)
        res_str.append(TBODY_CLOSE)
        res_str.append(TABLE_CLOSE)
        return "".join(res_str)

    def default_response(self,response_msg='A pretty minimal response'):
        """ A method to send a default response to the browser for testing purposes"""
        resp = []
        resp.append("Content-Type: text/plain")
        resp.append("")
        resp.append(response_msg)
        res_str = "\r\n".join(resp)
        return res_str

if __name__ == '__main__':
    form = cgi.FieldStorage()
    date = form.getfirst('stDate','2017-06-10')
    recordID = form.getfirst('record','')
    param_name = form.getfirst('param','NONE')
    context_name = form.getfirst('context','PARTS')
    param_value = form.getfirst('paramVal','')
    aggr_flag = form.getfirst('aggr','false')
    exact_flag = form.getfirst('exactFlag','true')
    #result_flag = form.getfirsti('aggrFlag','NO')
    model = ResultModel(date,recordID,param_name,context_name,param_value,aggr_flag,exact_flag)
    res_list = model.get_data()
    if aggr_flag == 'true':
        html_res = model.format_aggr_result(res_list)
    else:
        html_res = model.format_default_result(res_list)
    print(model.default_response(html_res))

