#!/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>
"""

import pdb
import io
import os.path
import sys
from mave.core import Preprocessor, ModelAggregator, MnV
from datetime import datetime
import argparse
import ConfigParser
import logging
import pkg_resources
import pprint

def mave(input_file=None,
         config_file=None,
         changepoint=None,
         **kwargs):
    kws ={}
    config = ConfigParser.ConfigParser(allow_no_value=True)
    if config_file: 
        try:
            if not os.path.isfile(config_file): raise Exception
        except Exception as e: 
            print e
            print 'Configuration file (%s) not found'%config_file
            sys.exit()
        config.read(config_file)
    else:
        # no config file passed, use defaults:
        print '\nNo config file entered - Using default settings' 
        resource_path = os.path.join('config', 'default.cfg')
        default = pkg_resources.resource_string('mave', resource_path)
        config.readfp(io.BytesIO(default))
    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)]
    logger.info('\nConfiguration used for this analysis:\n%s\n'%\
                pprint.pformat(kws))
    f = open(input_file, 'Ur')
    mnv = MnV(input_file=f,**kws)
    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")
    prs.add_argument("-ad", "--address", type=str,
                     help="address of the building")
    # 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")
    prs.add_argument("-pl", "--plot", action="store_true",
                     help="plot results to pdf")
    # 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,
                     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__)
