#!/usr/bin/python2 -s

from __future__ import print_function
import logging
import optparse
import os
import sys
from ansiblereview.version import __version__
from ansiblereview import classify
from ansiblereview.utils import error, info, warn, read_config
from appdirs import AppDirs


def get_candidates_from_diff(difftext):
    try:
        import unidiff
    except ImportError as e:
        raise SystemExit("Could not import unidiff library: %s", e.message)
    patch = unidiff.PatchSet(sys.stdin)

    candidates = []
    for patchedfile in [patchfile for patchfile in
                        patch.added_files + patch.modified_files]:
        if patchedfile.source_file == '/dev/null':
            candidates.append(patchedfile.path)
        else:
            lines = ",".join(["%s-%s" % (hunk.target_start, hunk.target_start + hunk.target_length)
                              for hunk in patchedfile])
            candidates.append("%s:%s" % (patchedfile.path, lines))
    return candidates


def main(args):
    config_dir = AppDirs("ansible-review", "com.github.willthames").user_config_dir
    default_config_file = os.path.join(config_dir, "config.ini")

    parser = optparse.OptionParser("%prog playbook_file|role_file|inventory_file",
                                   version="%prog " + __version__)
    parser.add_option('-c', dest='configfile', default=default_config_file,
                      help="Location of configuration file: [%s]" % default_config_file)
    parser.add_option('-d', dest='rulesdir',
                      help="Location of standards rules")
    parser.add_option('-r', dest='lintdir',
                      help="Location of additional lint rules")
    parser.add_option('-q', dest='log_level', action="store_const", default=logging.WARN,
                      const=logging.ERROR, help="Only output errors")
    parser.add_option('-v', dest='log_level', action="store_const", default=logging.WARN,
                      const=logging.INFO, help="Show more verbose output")

    options, args = parser.parse_args(args)
    settings = read_config(options.configfile)

    # Merge CLI options with config options. CLI options override config options.
    for key, value in settings.__dict__.iteritems():
        if not getattr(options, key):
            setattr(options, key, getattr(settings, key))

    if os.path.exists(options.configfile):
        info("Using configuration file: %s" % options.configfile, options, file=sys.stderr)
    else:
        warn("No configuration file found at %s" % options.configfile, options, file=sys.stderr)

    if len(args) == 0:
        candidates = get_candidates_from_diff(sys.stdin)
    else:
        candidates = args

    errors = 0
    for filename in candidates:
        if ':' in filename:
            (filename, lines) = filename.split(":")
        else:
            lines = None
        candidate = classify(filename)
        if candidate:
            if lines:
                info("Reviewing %s lines %s" % (candidate, lines), options)
            else:
                info("Reviewing all of %s" % candidate, options)
            errors = errors + candidate.review(options, lines)
        else:
            warn("Couldn't classify file %s" % filename, options)
    return errors


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