#!/usr/bin/python2
#
# This file is part of cclib (http://cclib.sf.net), a library for parsing
# and interpreting the results of computational chemistry packages.
#
# Copyright (C) 2006-2014, the cclib development team
#
# The library is free software, distributed under the terms of
# the GNU Lesser General Public version 2.1 or later. You should have
# received a copy of the license along with cclib. You can also access
# the full license online at http://www.gnu.org/copyleft/lgpl.html.

from __future__ import print_function

import getopt
import glob
import logging
import os
import sys

from cclib.parser import ccData, ccopen


msg_usage = """\
Usage:  ccget <attribute> [<attribute>] <compchemlogfile> [<compchemlogfile>]
Try     ccget --help for more information\
"""

msg_usage_long = """\
Usage:  ccget <attribute> [<attribute>] <compchemlogfile> [<compchemlogfile>]
    where <attribute> is one of the attributes to be parsed by cclib
    from each of the compchemlogfiles.
For a list of attributes available in a file, use --list (or -l):
    ccget --list <compchemlogfile>
To parse multiple files as one input stream, use --multi (or -m):
    ccget --multi <attr> [<attr>]  <cclogfile> <cclogfile> [<cclogfile>]\
"""


def main():

    # Parse the arguments, but print help information and exit if it fails.
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hlm", ["help", "list", "multi"])
    except getopt.GetoptError:
        print(msg_usage_long)
        sys.exit(2)

    showattr = False
    multifile = False
    for o, a in opts:
        if o in ("-h", "--help"):
            print(msg_usage_long)
            sys.exit()
        if o in ("-l", "--list"):
            showattr = True
        if o in ("-m", "--multi"):
            multifile = True

    # We need at least one attribute and the filename, so two arguments, or
    # just one filename if we want to list attributes that can be extracted.
    # In multifile mode, we generally want at least two filenames, so the
    # expected number of arguments is a bit different.
    if not multifile:
        correct_number = (not showattr and len(args) > 1) or (showattr and len(args) > 0)
    else:
        correct_number = (not showattr and len(args) > 2) or (showattr and len(args) > 1)
    if not correct_number:
        print("The number of arguments does not seem to be correct.")
        print(msg_usage)
        sys.exit()

    # Figure out which are the attribute names and which are the filenames.
    # Note that in Linux, the shell expands wild cards, but not so in Windows,
    # so try to do that here using glob.
    attrnames = []
    filenames = []
    for arg in args:
        if arg in ccData._attrlist:
            attrnames.append(arg)
        elif os.path.isfile(arg):
            filenames.append(arg)
        else:
            wildcardmatches = glob.glob(arg)
            if wildcardmatches:
                filenames.extend(wildcardmatches)
            else:
                print("%s is neither a filename nor an attribute name." % arg)
                print(msg_usage)
                sys.exit(1)

    # Since there is some ambiguity to the correct number of arguments, also check
    # that there is at least one filename to use (or two in multifile mode), and
    # at least one attribute to parse if the -l option was not passed.
    if len(filenames) == 0:
        print("No logfiles given")
        sys.exit(1)
    if multifile and len(filenames) == 1:
        print("Expecting at least two logfiles in multifile mode")
        sys.exit(1)
    if not showattr and len(attrnames) == 0:
        print("No attributes given")
        sys.exit(1)

    # This should be sufficient to correctly handle multiple files, that is to
    # to run the loop below only once with all logfiles in the variable `filename`.
    # Although, perhaps it would be clearer to abstract the contents of the loop
    # into another function.
    if multifile:
        filenames = [filenames]

    # Now parse each file and print out the requested attributes.
    for filename in filenames:

        name = (not multifile)*filename or ", ".join(filename[:-1]) + " and " + filename[-1]

        print("Attempting to parse %s" % name)
        log = ccopen(filename)
        if log == None:
            print("Cannot figure out what type of computation chemistry output file '%s' is." % name)
            print("Report this to the cclib development team if you think this is an error.")
            print(msg_usage)
            sys.exit()
              
        log.logger.setLevel(logging.ERROR)
        data = log.parse()
        if showattr:
            print("cclib can parse the following attributes from %s:" % name)
            for x in ccData._attrlist:
                if hasattr(data,x):
                    print("  %s" % x)
        else:
            invalid = False
            for attr in attrnames:
                if hasattr(data,attr):
                    print("%s:\n%s" % (attr,getattr(data,attr)))
                else:
                    print("Could not parse %s from this file." % attr)
                    invalid = True
            if invalid:
                print(msg_usage_long)


if __name__ == "__main__":
    main()
