#!/usr/bin/python
"""
Building Energy Prediction

This software reads an input file (a required argument) containing 
building energy data in a format similar to example file. 
It then trains a model and estimates the error associated
with predictions using the model.

@author Paul Raftery <p.raftery@berkeley.edu>
@author Tyler Hoyt <thoyt@berkeley.edu>
"""

from mave.core import Preprocessor, ModelAggregator, SingleModelMnV
from datetime import datetime
import pdb
import os.path
import argparse, ConfigParser, logging

def mave(input_file=None,
         changepoint=None,
         test_size=0.25,
         config_file=None,
         **kwargs):
    config = ConfigParser.ConfigParser()
    if os.path.isfile(config_file):
        config.read(config_file)
        kws ={}
        for name in config.options('Booleans'):
            kws[name] = config.getboolean('Booleans', name)
        for name in config.options('Integers'):
            kws[name] = config.getint('Integers', name)
        for name in config.options('Floats'):
            kws[name] = config.getfloat('Floats', name)
        for name in config.options('Strings'):
            kws[name] = config.get('Strings', name)
        for name in config.options('Lists'):
            kws[name] = config.get('Lists', name).replace(' ' ,'').split(',')
        kws['changepoints'] = config.items('Changepoints')
        if not kws['changepoints']: kws['changepoints'] = None 
        # remove unused command line args (value is None)
        kwargs = {key: value for (key, value) in kwargs.iteritems() if value}
        # override config file values using command line args
        kws.update(kwargs)
        # if user enters a single changepoint at command line, use it 
        if changepoint: 
            kws['changepoints'] = [(changepoint,Preprocessor.POST_DATA_TAG)]
        f = open(input_file, 'Ur')
        mnv = SingleModelMnV(input_file=f,**kws)
    else:
        print '\nUsing default settings as no valid config file was found\n' 
        f = open(input_file, 'Ur')
        if changepoint: 
            cp = [(changepoint,Preprocessor.POST_DATA_TAG)]
            mnv = SingleModelMnV(input_file=f,changepoints=cp)
        else:
            mnv = SingleModelMnV(input_file=f,test_size=test_size)
    logger.info(mnv)

if __name__=='__main__': 
    # parse args
    prs = argparse.ArgumentParser()
    # required argument
    prs.add_argument("input_file", 
                     help="filename for input data")
    # identification of the post-retrofit period
    prs.add_argument("-cp", "--changepoint", 
                     help="datetime at which post-retrofit period begins")
    prs.add_argument("-ts", "--test_size", type=float,
                     help="fraction of the file used as post_retrofit period")
    # output controls
    prs.add_argument("-v", "--verbose", action="store_true",
                     help="increase output verbosity")
    prs.add_argument("-p", "--print_screen", action="store_true",
                     help="print to screen as well as log file")
    prs.add_argument("-s", "--save", action="store_true",
                     help="save model and output detailed results")
    # high level controls on total computation time
    prs.add_argument("-n", "--n_jobs", type=int,
                     help="num parallel jobs (default uses max available")
    prs.add_argument("-k", "--k", type=int, 
                     help="num folds in k-fold cross-validation")
    prs.add_argument("-si", "--search_iterations", type=int, 
                     help="num search iterations in randomized grid search")
    # option to provide more advanced control using a configuration file
    prs.add_argument("-conf", "--config_file", type=str, default='default.cfg',
                     help="use specified config file for more advanced input")
    args = prs.parse_args()  
    
    # set up logging to screen and file
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)
    fo = logging.FileHandler("mave.log")
    fo.setLevel(logging.INFO)
    logger.addHandler(fo)
    if args.print_screen:
    # log to screen also
        po = logging.StreamHandler()
        po.setLevel(logging.INFO)
        logger.addHandler(po)
    logger.info("\nAssessing input file: %s" % args.input_file)
    
    mave(**args.__dict__)
