###############################################################################
# Copyright IBM Corp. and others 2016
#
# This program and the accompanying materials are made available under
# the terms of the Eclipse Public License 2.0 which accompanies this
# distribution and is available at https://www.eclipse.org/legal/epl-2.0/
# or the Apache License, Version 2.0 which accompanies this distribution and
# is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# This Source Code may also be made available under the following
# Secondary Licenses when the conditions for such availability set
# forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
# General Public License, version 2 with the GNU Classpath
# Exception [1] and GNU General Public License, version 2 with the
# OpenJDK Assembly Exception [2].
#
# [1] https://www.gnu.org/software/classpath/license.html
# [2] https://openjdk.org/legal/assembly-exception.html
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
###############################################################################

import os
import subprocess

class ToolOutput:
   '''Represents the output generated by a call to tool.'''

   def __init__(self, returncode, stderr, stdout):
      self.returncode = returncode  # the return code of the command
      self.stderr = stderr          # the standard error output of the command
      self.stdout = stdout          # the standard output of the command

   @staticmethod
   def fromProcess(proc):
      '''Constructs output object from process object'''

      return ToolOutput(proc.returncode, proc.stderr.read(), proc.stdout.read())


class ToolExecutionLog:
   '''Represents a log of a tool invocation/execution.'''

   def __init__(self, args, cmd, output):
      self.args = args
      self.cmd = cmd
      self.cmdstr = ' '.join(cmd)
      self.output = output

      
class Tool(object):
   '''A wrapper providing an interface for interacting with a tool.'''
   
   def __init__(self, cmdBuilder, env={}):
      self.cmdBuilder = cmdBuilder
      self.env = env
   
   def call(self, args):
      '''Calls the tool with the required arguments.'''

      command = self.cmdBuilder(args)

      p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.env)
      p.wait()

      output = ToolOutput.fromProcess(p)
      log = ToolExecutionLog(args, command, output)

      p.stdout.close()
      p.stderr.close()

      return log
