# -*- coding: utf-8 -*-
"""
Created on Wed Sep 17 13:47:34 2014

@author: Slawomir Figiel
"""

import click
import scipy.io
from os.path import isfile
from numpy import average as avr, std as nstd, load
from matrixmultiplication import multiply_cpu, multiply_ellpack, \
                                 multiply_sliced, multiply_sertilp, \
                                 multiply_ertilp, multiply_csr
from matrixutilites import string_vector, result_equals, dict_vector_paths
from filesutilites import path_reduction, sort_paths

COLORS = {'success' : 'green',
          'info' : 'cyan',
          'danger' : 'red',
          'warning' : 'yellow'
         }

@click.command()
@click.option('-b', '--block', default=128,
              help='Block size for CUDA. Default: 128')
@click.option('-ss', '--slice-size', 'ss', default=64,
              help='Slice size for ...Ellpack. Default: 64')
@click.option('-tpr', '--thread-per-row', 'tpr', default=2,
              help='Thread per row. Default: 2')
@click.option('-a', '--align', default=32,
              help='Align const for Ellpack. Default: 32')
@click.option('-p', '--prefetch', default=2,
              help='PreFetch for SlicedEllpack. Default: 2')
@click.option('-r', '--repeat', default=1,
              help='Count of repetitions calculations. Deafult: 1')

@click.option('-csr', '--csr', 'csr', is_flag=True, help='Use CSR format')
@click.option('-ell', '--ellpack', 'ell', is_flag=True,
              help='Use Ellpack format')
@click.option('-sle', '--sliced', 'sle', is_flag=True,
              help='Use Sliced Ellpack format')
@click.option('-see', '--sertilp', 'see', is_flag=True,
              help='Use Sertilp Ellpack format')
@click.option('-ert', '--ertilp', 'ert', is_flag=True,
              help='Use Ertilp format')
@click.option('-cpu', '--cpu', 'cpu', is_flag=True,
              help='Use CPU method multiplication (without GPU) on Numpy')

@click.option('-rst', '--result', is_flag=True,
              help='Print result multiplication.')
@click.option('-t', '--time', is_flag=True,
              help='Print list of time multiplication')
@click.option('-avr', '--avrtime', is_flag=True,
              help='Print average time multiplication')
@click.option('-std', '--standard-deviation', 'std', is_flag=True,
              help='Print standard deviation of time multiplication')
@click.option('--test', type=click.FLOAT,
              help='Testing result multiplication. Print bad row. Value is '
                   'confidence factor.')
@click.option('-com', '--compensate', 'com', type=click.INT,
              help='N first time are remove (returned times decremented '
                   'by n). Recommended in testing the speed, because the n '
                   'first times (e. g. one) are a long delay.')
@click.option('-o', '--output', type=click.File(mode='a', lazy=True),
              help='File to save raport. Format CSV. If exist append new '
                   'data. Added to the file it info if it is created.')
@click.option('-param', '--parameters', is_flag=True,
              help='Print value of parameters.')
@click.option('-sep', '--separator', 'sep', default='; ',
              help='Separator for data in report. Default: "; "')

@click.argument('vector-path', nargs=1, required=True,
                type=click.Path(exists=True))
@click.argument('matrix-path', nargs=1, required=True,
                type=click.Path(exists=True))
def cli(block, ss, tpr, align, prefetch, csr, ell, sle, see, ert, cpu,
        repeat, result, time, avrtime, std, test, com, output, parameters,
        vector_path, sep, matrix_path):
    '''
    Command line interface for test execute matrix multiplication.
    '''
    eol = '\n'
    param = {'Block' : str(block),
             'Slice size' : str(ss),
             'Threads per row' : str(tpr),
             'Align' : str(align),
             'Prefetch' : str(prefetch),
             'Repeat' : str(repeat),
             'Compensate' : str(com) if com else '0'
            }
    vectors_dict = dict_vector_paths(
                    sort_paths(path_reduction(
                        [str(vector_path),]), '.npy')
                    ['.npy'])
    matrices_paths = sort_paths(
                        path_reduction(
                            [str(matrix_path),]),
                            '.mtx')['.mtx']

    if com:
        repeat += com
    #Print parameters
    if parameters:
        click.secho(_get_msg('paramInfo'), fg=COLORS['info'])
        param_rows = []
        for key, value in param.items():
            param_rows.append('  {0:<20}{1}'.format(key, value))
        click.echo('\n'.join(param_rows))
    #Create file and add headers
    if output and not isfile(output.name):
        output.write(sep.join(param.keys()) + eol)
        output.write(sep.join(param.values()) + eol)
        output.write(eol)
        headers = ['matrix', 'format', 'average time',
                   'standard deviation time', 'times']
        output.write(sep.join(headers) + eol)

    for matrix_path in matrices_paths:
        try:
            matrix = scipy.io.mmread(matrix_path)