#  _________________________________________________________________________
#
#  Coopr: A COmmon Optimization Python Repository
#  Copyright (c) 2008 Sandia Corporation.
#  This software is distributed under the BSD License.
#  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
#  the U.S. Government retains certain rights in this software.
#  For more information, see the Coopr README.txt file.
#  _________________________________________________________________________

__all__ = ['PicoMIPConverter']

from coopr.opt.base import *

from pyutilib.component.core import *
from pyutilib.component.config import *
from pyutilib.component.executables import *
import pyutilib.services
import pyutilib.common
import pyutilib.subprocess


class PicoMIPConverter(ManagedSingletonPlugin):

    implements(IProblemConverter)

    executable = ExtensionPoint(IExternalExecutable)

    def __init__(self,**kwds):
        ManagedSingletonPlugin.__init__(self,**kwds)

    def can_convert(self, from_type, to_type):
        """Returns true if this object supports the specified conversion"""
        #
        # Test if the glpsol executable is available
        #
        if self.executable.service("pico_convert") is None:
            return False
        #
        # Return True for specific from/to pairs
        #
        if from_type == ProblemFormat.nl and to_type == ProblemFormat.cpxlp:
            return True
        if from_type == ProblemFormat.nl and to_type == ProblemFormat.mps:
            return True
        if from_type == ProblemFormat.mps and to_type == ProblemFormat.cpxlp:
            return True
        if from_type == ProblemFormat.cpxlp and to_type == ProblemFormat.mps:
            return True
        return False

    def available(self):
        cmd = self.executable.service("pico_convert")
        return not cmd is None

    def apply(self, *args, **kwargs):
        """
        Run the external pico_convert utility
        """
        if len(args) != 3:
            raise ConverterError("Cannot apply pico_convert with more than one filename or model")
        cmd = self.executable.service("pico_convert")
        if cmd is None:
            raise ConverterError("The 'pico_convert' application cannot be found")

        pico_convert_cmd = cmd.get_path()
        target=str(args[1])
        if target=="cpxlp":
            target="lp"
        # NOTE: if you have an extra "." in the suffix, the pico_convert program fails to output to the correct filename.
        output_filename = pyutilib.services.TempfileManager.create_tempfile(suffix = 'pico_convert.' + target)
        if not isinstance(args[2],basestring):
            fname= pyutilib.services.TempfileManager.create_tempfile(suffix= 'pico_convert.' +str(args[0]))
            args[2].write(filename=fname, format=args[1])
            cmd = pico_convert_cmd +" --output="+output_filename+" "+target+" "+fname
        else:
            cmd = pico_convert_cmd +" --output="+output_filename+" "+target
            for item in args[2:]:
                if not os.path.exists(item):
                    raise ConverterError("File "+item+" does not exist!")
                cmd = cmd + " "+item
        print("Running command: "+cmd)
        pyutilib.subprocess.run(cmd)
        if not os.path.exists(output_filename):       #pragma:nocover
            raise pyutilib.common.ApplicationError(\
                    "Problem launching 'pico_convert' to create "+output_filename)
        return (output_filename,),None # no variable map at the moment
