#!/usr/bin/python

"""
Selects all rows and columns that satisfy the condition specified
and draws the matrix. There is a seperate SQL query made for every (x,y)
in the matrix.
"""

print "Content-type: text/html\n"

import sys, os, urllib, cgi, cgitb, re, datetime, time

total_wall_time_start = time.time()

import common
from autotest_lib.tko import display, frontend, db, query_lib
from autotest_lib.client.common_lib import kernel_versions

html_header = """\
<form action="/tko/compose_query.cgi" method="get">
<table border="0">
<tr>
  <td>Column: </td>
  <td>Row: </td>
  <td>Condition: </td>
  <td align="center">
  <a href="http://autotest.kernel.org/wiki/AutotestTKOCondition">Help</a>
  </td>
</tr>
<tr>
  <td>
  <SELECT NAME="columns">
  %s
 </SELECT>
  </td>
  <td>
  <SELECT NAME="rows">
  %s
  </SELECT>
  </td>
  <td>
    <input type="text" name="condition" size="30" value="%s">
    <input type="hidden" name="title" value="%s">
  </td>
  <td align="center"><input type="submit" value="Submit">
  </td>
</tr>
</table>
</form>
<form action="/tko/save_query.cgi" method="get">
<table border="0">
<tr>
 <td>Name your query:&nbsp;&nbsp;</td>
  <td>
    <input type="text" name="label" size="15" value="">
  </td>
  <td align="center">&nbsp;<input type="submit" value="Save Query">
  </td>
 <td>&nbsp;&nbsp;<a href="/tko/query_history.cgi">View saved queries</a></td>
  <td>
    <input type="hidden" name="columns" value="%s">
    <input type="hidden" name="rows" value="%s">
    <input type="hidden" name="condition" value="%s">
  </td>
</tr>
</table>
</form>
"""


next_field = {
    'machine_group': 'hostname',
    'hostname': 'tag',
    'tag': 'tag',

    'kernel': 'test',
    'test': 'label',
    'label': 'tag',

    'reason': 'tag',
    'user': 'tag',
    'status': 'tag',
   
    'time': 'tag',
    'time_daily': 'time',
}


def parse_field(form, form_field, field_default):
    if not form_field in form:
        return field_default
    field_input = form[form_field].value.lower()
    if field_input and field_input in frontend.test_view_field_dict:
        return field_input
    return field_default


def parse_condition(form, form_field, field_default):
    if not form_field in form:
        return field_default
    return form[form_field].value


form = cgi.FieldStorage()

title_field = parse_condition(form, 'title', '')
row = parse_field(form, 'rows', 'kernel')
column = parse_field(form, 'columns', 'machine_group')
condition_field = parse_condition(form, 'condition', '')

if 'brief' in form.keys() and form['brief'].value <> '0':
    display.set_brief_mode()

## caller can specify rows and columns that shall be included into the report
## regardless of whether actual test data is available yet
force_row_field = parse_condition(form,'force_row','')
force_column_field = parse_condition(form,'force_column','')


def split_forced_fields(force_field):
    if force_field:
        return force_field.split()
    else:
        return []

force_row =  split_forced_fields(force_row_field)
force_column =  split_forced_fields(force_column_field)
  
cgitb.enable()
db_obj = db.db()


def construct_link(x, y):
    next_row = row
    next_column = column
    condition_list = []
    if condition_field != '':
        condition_list.append(condition_field)
    if y:
        next_row = next_field[row]
        condition_list.append("%s='%s'" % (row, y))
    if x:
        next_column = next_field[column]
        condition_list.append("%s='%s'" % (column, x))
    next_condition = '&'.join(condition_list)
    link = '/tko/compose_query.cgi?' + urllib.urlencode({'columns': next_column,
               'rows': next_row, 'condition': next_condition,
               'title': title_field})
    return link


def construct_logs_link(x, y, job_tag):
    job_path = frontend.html_root + job_tag + '/'
    test = ''
    if (row == 'test' and
        not y.split('.')[0] in ('boot', 'build', 'install')):
        test = y
    if (column == 'test' and
        not x.split('.')[0] in ('boot', 'build', 'install')):
        test = x
    return '/tko/retrieve_logs.cgi?' + urllib.urlencode({'job' : job_path,
         'test' : test})


def create_select_options(selected_val):
    ret = ""
    for option in sorted(frontend.test_view_field_dict.keys()):
        if selected_val == option:
            selected = " SELECTED"
        else:
            selected = ""

        ret += '<OPTION VALUE="%s"%s>%s</OPTION>\n' % \
                        (option, selected, option)
    return ret


def map_kernel_base(kernel_name):
    ## insert <br> after each / in kernel name
    ## but spare consequtive //
    kernel_name = kernel_name.replace('/','/<br>')
    kernel_name = kernel_name.replace('/<br>/<br>','//')
    return kernel_name


def header_tuneup(field_name, header):
        ## header tune up depends on particular field name and may include:
        ## - breaking header into several strings if it is long url
        ## - creating date from datetime stamp
        ## - possibly, expect more various refinements for different fields
        if field_name == 'kernel':
                return  map_kernel_base(header)
        else:
                return header


# Kernel name mappings -- the kernels table 'printable' field is
# effectively a sortable identifier for the kernel It encodes the base
# release which is used for overall sorting, plus where patches are
# applied it adds an increasing pNNN patch combination identifier
# (actually the kernel_idx for the entry).  This allows sorting
# as normal by the base kernel version and then sub-sorting by the
# "first time we saw" a patch combination which should keep them in
# approximatly date order.  This patch identifier is not suitable
# for display, so we have to map it to a suitable html fragment for
# display.  This contains the kernel base version plus the truncated
# names of all the patches,
#
#     2.6.24-mm1 p112
#     +add-new-string-functions-
#     +x86-amd-thermal-interrupt
# 
# This mapping is produced when the first mapping is request, with
# a single query over the patches table; the result is then cached.
#
# Note: that we only count a base version as patched if it contains
# patches which are not already "expressed" in the base version.
# This includes both -gitN and -mmN kernels.
map_kernel_map = None


def map_kernel_init():
    fields = ['base', 'k.kernel_idx', 'name', 'url']
    map = {}
    for (base, idx, name, url) in db_obj.select(','.join(fields),
            'tko_kernels k, tko_patches p', 'k.kernel_idx=p.kernel_idx'):
        match = re.match(r'.*(-mm[0-9]+|-git[0-9]+)\.(bz2|gz)$', url)
        if match:
            continue

        key = base + ' p%d' % (idx)
        if not map.has_key(key):
            map[key] = map_kernel_base(base) + ' p%d' % (idx)
        map[key] += ('<br>+<span title="' + name + '">' +
                 name[0:25] + '</span>')

    return map


def map_kernel(name):
    global map_kernel_map
    if map_kernel_map is None:
        map_kernel_map = map_kernel_init()

    if map_kernel_map.has_key(name):
        return map_kernel_map[name]

    return map_kernel_base(name.split(' ')[0])


field_map = {
    'kernel':map_kernel
}

sql_wall_time = 0

def gen_matrix():
    where = None
    if condition_field.strip() != '':
        try:
            where = query_lib.parse_scrub_and_gen_condition(
                condition_field, frontend.test_view_field_dict)
            print "<!-- where clause: %s -->" % (where,)
        except:
            msg = "Unspecified error when parsing condition"
            return [[display.box(msg)]]

    wall_time_start = time.time()
    try:
        ## Unfortunately, we can not request reasons of failure always
        ## because it may result in an inflated size of data transfer
        ## (at the moment we fetch 500 bytes of reason descriptions into
        ## each cell )
        ## If 'status' in [row,column] then either width or height
        ## of the table <=7, hence table is not really 2D, and
        ## query_reason is relatively save.
        ## At the same time view when either rows or columns grouped
        ## by status is when users need reasons of failures the most.
        
        ## TO DO: implement [Show/Hide reasons] button or link in
        ## all views and make thorough performance testing 
        test_data = frontend.get_matrix_data(db_obj, column, row, where,
                query_reasons = ('status' in [row,column])
                )
        global sql_wall_time
        sql_wall_time = time.time() - wall_time_start

    except db.MySQLTooManyRows, error:
        return [[display.box(str(error))]]            
    
    for f_row in force_row:
        if not f_row in test_data.y_values:
            test_data.y_values.append(f_row)
    for f_column in force_column:
        if not f_column in test_data.x_values:
            test_data.x_values.append(f_column)

    if not test_data.y_values:
        msg = "There are no results for this query (yet?)."
        return [[display.box(msg)]]

    dict_url = {'columns': row,
               'rows': column, 'condition': condition_field,
               'title': title_field}
    link = '/tko/compose_query.cgi?' + urllib.urlencode(dict_url)
    header_row = [display.box("<center>(Flip Axis)</center>", link=link)]

    for x in test_data.x_values:
        dx = x
        if field_map.has_key(column):
            dx = field_map[column](x)
        x_header = header_tuneup(column, dx)
        link = construct_link(x, None)
        header_row.append(display.box(x_header,header=True,link=link))

    matrix = [header_row]
    # For each row, we are looping horizontally over the columns.
    for y in test_data.y_values:
        dy = y
        if field_map.has_key(row):
            dy = field_map[row](y)
        y_header = header_tuneup(row, dy)
        link = construct_link(None, y)
        cur_row = [display.box(y_header, header=True, link=link)]
        for x in test_data.x_values:
            ## next 2 lines: temporary, until non timestamped
            ## records are in the database
            if x==datetime.datetime(1970,1,1): x = None
            if y==datetime.datetime(1970,1,1): y = None
            try:
                box_data = test_data.data[x][y]
            except:
                cur_row.append(display.box(None, None, 
                           row_label=y, column_label=x))
                continue
            job_tag = test_data.data[x][y].job_tag
            if job_tag:
                link = construct_logs_link(x, y, job_tag)
            else:
                link = construct_link(x, y)

            apnd = display.status_precounted_box(db_obj, box_data,
                                 link, y, x)
            cur_row.append(apnd)
        matrix.append(cur_row)
    return matrix


def main():
    if display.is_brief_mode():
        ## create main grid table only as provided by gen_matrix()
        display.print_table(gen_matrix())
    else:
        # create the actual page 
        print '<html><head><title>'
        print 'Filtered Autotest Results'
        print '</title></head><body>'
        display.print_main_header()
        print html_header % (create_select_options(column),
                     create_select_options(row),
                     condition_field, title_field,
                     ## history form
                     column,row,condition_field)
        if title_field:
            print '<h1> %s </h1>' % (title_field)
        print display.color_keys_row()
        display.print_table(gen_matrix())
        print display.color_keys_row()
        total_wall_time = time.time() - total_wall_time_start
        
        perf_info = '<p style="font-size:x-small;">'
        perf_info += 'sql access wall time = %s secs,' % sql_wall_time
        perf_info += 'total wall time = %s secs</p>' % total_wall_time
        print perf_info
        print '</body></html>'


main()
