#! /usr/bin/env python
# -*- coding: utf-8 -*-

from pdb.dpr import *
from pdb.dprc import *
import pdb
import os.path

if __name__ == "__main__":
    from optparse import OptionParser

    def generate_pattern(model, query):
        if options.init:
            return version_0(model, query)
        elif options.safe:
            return version_S(model, query)
        elif options.local:
            return version_L(model, query)
        elif options.safe_local:
            return version_SL(model, query)
        elif options.local_safe:
            return version_LS(model, query)
        elif options.dprc:
            dprc = DprcPatternGenerator(model, query, options.MAX)
            return dprc.generate_pattern()
        return Pattern()


    def greedy_with_pdb(model, query, pdbfile):
        cmd = Command("MCTA -o2 -h4 --pdb=%s %s %s" % (pdbfile, model, query))
        print "Property:", cmd.parser.property
        if cmd.parser.property == "satisfied":
            print "states: %8d, time: %7.2f, trace: %7d" % (cmd.parser.states, cmd.parser.usr_time + cmd.parser.sys_time, cmd.parser.trace)
        else:
            print "search: %7.2f s" % (cmd.parser.sys_time + cmd.parser.usr_time)


    def astar_with_pdb(model, query, pdbfile):
        cmd = Command("MCTA -o3 -h4 --pdb=%s %s %s" % (pdbfile, model, query))
        print "Property:", cmd.parser.property
        if cmd.parser.property == "satisfied":
            print "states: %8d, time: %7.2f, trace: %7d" % (cmd.parser.states, cmd.parser.usr_time + cmd.parser.sys_time, cmd.parser.trace)
        else:
            print "search: %7.2f s" % (cmd.parser.sys_time + cmd.parser.usr_time)

    op = OptionParser(usage="%prog [options] <model file> <query file>")
    # misc options
    op.add_option("-d", action="store_true", default=False,
                  help="enable logging", dest="debug")
    op.add_option("-v", action="store_true", default=False,
                  help="be verbose", dest="verbose")
    # search methods
    op.add_option("--astar", action="store_true", default=False,
                  help="do an A* search", dest="astar")
    op.add_option("--greedy", action="store_true", default=False,
                  help="do a greedy search", dest="greedy")
    # pattern selection methods
    op.add_option("--init", action="store_true", default=False,
                  help="safe abstraction before local search", dest="init")
    op.add_option("--sl", action="store_true", default=False,
                  help="safe abstraction before local search", dest="safe_local")
    op.add_option("--ls", action="store_true", default=False,
                  help="local search before safe abstraction", dest="local_safe")
    op.add_option("--l", action="store_true", default=False,
                  help="only local search", dest="local")
    op.add_option("--s", action="store_true", default=False,
                  help="only safe abstraction", dest="safe")
    op.add_option("--dprc", action="store_true", default=False,
                  help="use dprc strategy", dest="dprc")
    op.add_option("--max-time", dest="MAX", type="int", default=2,
                  help="time limit for fast reachability tests (dprc)")

    options, args = op.parse_args()
    if options.__dict__.values() == 10*[False]:
        options.astar = True
        options.safe_local = True
    if len(args) != 2:
        print "Error: two input files are required."
        exit(1)
    else:
        for arg in args:
            if not os.path.exists(arg):
                print "Error: input file '%s' does not exist." % arg
                exit(1)

    model, query = args

    pattern = generate_pattern(model, query)
    pdb_builder = pdb.PDBBuilder()
    pdb = pdb_builder.gen_pdb(model, query, pattern)
    if options.astar:
        astar_with_pdb(model, query, pdb)
    elif options.greedy:
        greedy_with_pdb(model, query, pdb)
