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

import tempfile
import os
from command import Command
from pattern import Pattern

def _mkfile(name):
    """private function used to generate temporary files. The provided
    name is the prefix used for the temp file"""
    base, ext = os.path.splitext(name)
    base = os.path.basename(base)
    res = tempfile.NamedTemporaryFile(prefix="%s-" % base, suffix=ext, delete=False)
    return res.name

class Abstractor(object):
    def __init__(self):
        self.time = 0.0

    def gen_abstraction(self, model, pattern, pdb=False):
        """If pdb is True, then the header for the pdb file is
        created."""
        basename, ext = os.path.splitext(model)
        result = _mkfile("%s.abs" % basename)
        absfile = _mkfile("%s.abs" % basename)
        if pdb:
            pdbfile = _mkfile("%s.pdb" % basename)
            cmd = Command("ABSTRACTOR %s -k -o -f %s %s > %s" % (model, pdbfile, pattern, absfile))
            self.time += cmd.parser.sys_time + cmd.parser.usr_time
            return absfile, pdbfile
        else:
            cmd = Command("ABSTRACTOR %s -k -o %s > %s" % (model, pattern, absfile))
            self.time += cmd.parser.sys_time + cmd.parser.usr_time
            return absfile

    def get_safe_vars(self, model):
        cmd = Command("SAFEABS %s" % model)
        self.time += cmd.parser.sys_time + cmd.parser.usr_time
        return Pattern(pattern=cmd.parser.safe_vars.split())

class PDBBuilder(object):
    def __init__(self):
        self.time = 0.0
        self.states = 0

    def gen_statespace(self, model, query):
        """dumps the entire reachable state space of model into a file and
        returns the name of this file."""
        basename, ext = os.path.splitext(model)
        space = _mkfile("%s.space" % basename)
        cmd = Command("MCTA -o0 -b --dump-state-space=%s %s %s" % (space, model, query))
        self.states = cmd.parser.states
        self.time += cmd.parser.sys_time + cmd.parser.usr_time
        return space

    def gen_pdb(self, model, query, pattern):
        """This function returns the filename of the PDB for the given
        model induced by the given pattern."""
        abstr = Abstractor()
        abstraction, pdbfile = abstr.gen_abstraction(model, pattern, pdb=True)
        space = self.gen_statespace(abstraction, query)
        cmd = Command("GRAPH -m -o %s %s" % (pdbfile, space))
        self.time += cmd.parser.sys_time + cmd.parser.usr_time + abstr.time
        print "PDB construction: %7.2f s, states: %d" % (self.time, self.states)
        return pdbfile
    

