#!/usr/bin/env python

import sys
import getopt

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from esgcet.config import loadConfig, getHandlerByName, registerHandlers, initLogging, splitRecord
from esgcet.query import printResult, queryDatasets, parseQuery, getQueryFields

usage = """Usage:
    esglist_datasets [options] project

    -or-

    esglist_datasets --list-projects

    List the published datasets matching the specified options.
    The second form lists configured projects.

Arguments:
    project: Project identifier

Options:

    --all:
        List all dataset versions.

    --echo-sql:
        Echo SQL commands

    --experiment experiment_id:
        Experiment identifier.

    -h, --help:
        Print a help message.

    -i init_dir:
        Directory containing all initialization files.
        Recommended: one initialization file for the default sections (esg.ini) and one per project, must match the name format esg.<project>.ini
        If not specified, the default installed init files are read.

    --list-projects:
        List all projects in the configuration file.

    --list-properties:
        List the properties for this project.

    --model model_id:
        Model identifier.

    --no-header:
        Do not print heading and trailing lines.

    -p, --property 'name=value':
        Property/value pair. value may use '%' as a wildcard character.

    --select property,property,...,property
        Select the specific properties to be printed. The list is comma-separated.

Notes:
    - To force a property to be listed, specify -p name=%

"""

def main(argv):

    try:
        args, lastargs = getopt.getopt(argv, "hi:p:", ['all', 'echo-sql', 'experiment=', 'help', 'list-projects', 'list-properties', 'model=',  'no-header', 'project=', 'property=', 'select='])
    except getopt.error:
        print sys.exc_value
        print usage
        sys.exit(0)

    echoSql = False
    init_dir = '/esg/config/esgcet/'
    listAll = False
    listProjects = False
    listProperties = False
    printHeaders = True
    properties = {}
    selectList = None
    for flag, arg in args:
        if flag=='--all':
            listAll = True
        elif flag=='--echo-sql':
            echoSql = True
        elif flag=='--experiment':
            name, op, value = parseQuery('experiment=%s'%arg)
            properties['experiment'] = (op, value)
        elif flag in ['-h', '--help']:
            print usage
            sys.exit(0)
        elif flag=='-i':
            init_dir = arg
        elif flag=='--list-projects':
            listProjects = True
        elif flag=='--list-properties':
            listProperties = True
        elif flag=='--model':
            name, op, value = parseQuery('model=%s'%arg)
            properties['model'] = (op, value)
        elif flag=='--no-header':
            printHeaders = False
        elif flag in ['-p', '--property']:
            name, op, value = parseQuery(arg)
            properties[name] = (op, value)
        elif flag=='--select':
            selectList = arg

    if not listProjects:
        if len(lastargs)==1:
            projectName = lastargs[0]
        else:
            print "No project specified."
            print usage
            sys.exit(0)

    # Load the configuration and set up a database connection
    config = loadConfig(init_dir)
    engine = create_engine(config.getdburl('extract'), echo=echoSql, pool_recycle=3600)
    initLogging('DEFAULT', override_sa=engine)
    Session = sessionmaker(bind=engine, autoflush=True, autocommit=False)

    # Register project handlers
    if not listProjects:
        registerHandlers()
        handler = getHandlerByName(projectName, None, Session)

    if listProperties:
        headers = getQueryFields(handler)
        print headers
    elif listProjects:
        projectOption = config.get('initialize', 'project_options')
        projectSpecs = splitRecord(projectOption)
        for projectName, projectDesc, search_order in projectSpecs:
            print '%s:\t%s'%(projectName, projectDesc)
    else:
        result, headers = queryDatasets(projectName, handler, Session, properties, select=selectList, listall=listAll)
        printResult(headers, result, printHeaders=printHeaders)

if __name__=='__main__':
    main(sys.argv[1:])
