# Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Fork from commands.py and output.py in v8 test driver.

import os
import signal
import subprocess
import sys
from threading import Event, Timer

import v8_fuzz_config

PYTHON3 = sys.version_info >= (3, 0)

# List of default flags passed to each d8 run.
DEFAULT_FLAGS = [
  '--correctness-fuzzer-suppressions',
  '--expose-gc',
  '--fuzzing',
  '--allow-natives-for-differential-fuzzing',
  '--invoke-weak-callbacks',
  '--omit-quit',
  '--es-staging',
  '--wasm-staging',
  '--no-wasm-async-compilation',
  '--suppress-asm-messages',
]

BASE_PATH = os.path.dirname(os.path.abspath(__file__))

# List of files passed to each d8 run before the testcase.
DEFAULT_MOCK = os.path.join(BASE_PATH, 'v8_mock.js')

# Suppressions on JavaScript level for known issues.
JS_SUPPRESSIONS = os.path.join(BASE_PATH, 'v8_suppressions.js')

# Config-specific mock files.
ARCH_MOCKS = os.path.join(BASE_PATH, 'v8_mock_archs.js')
WEBASSEMBLY_MOCKS = os.path.join(BASE_PATH, 'v8_mock_webassembly.js')


def _startup_files(options):
  """Default files and optional config-specific mock files."""
  files = [DEFAULT_MOCK]
  if not options.skip_suppressions:
    files.append(JS_SUPPRESSIONS)
  if options.first.arch != options.second.arch:
    files.append(ARCH_MOCKS)
  # Mock out WebAssembly when comparing with jitless mode.
  if '--jitless' in options.first.flags + options.second.flags:
    files.append(WEBASSEMBLY_MOCKS)
  return files


class BaseException(Exception):
  """Used to abort the comparison workflow and print the given message."""
  def __init__(self, message):
    self.message = message


class PassException(BaseException):
  """Represents an early abort making the overall run pass."""
  pass


class FailException(BaseException):
  """Represents an early abort making the overall run fail."""
  pass


class Command(object):
  """Represents a configuration for running V8 multiple times with certain
  flags and files.
  """
  def __init__(self, options, label, executable, config_flags):
    self.label = label
    self.executable = executable
    self.config_flags = config_flags
    self.common_flags =  DEFAULT_FLAGS[:]
    self.common_flags.extend(['--random-seed', str(options.random_seed)])

    self.files = _startup_files(options)

  def run(self, testcase, timeout, verbose=False):
    """Run the executable with a specific testcase."""
    args = [self.executable] + self.flags + self.files + [testcase]
    if verbose:
      print('# Command line for %s comparison:' % self.label)
      print(' '.join(args))
    if self.executable.endswith('.py'):
      # Wrap with python in tests.
      args = [sys.executable] + args
    return Execute(
        args,
        cwd=os.path.dirname(os.path.abspath(testcase)),
        timeout=timeout,
    )

  @property
  def flags(self):
    return self.common_flags + self.config_flags


class Output(object):
  def __init__(self, exit_code, stdout, pid):
    self.exit_code = exit_code
    self.stdout = stdout
    self.pid = pid

  def HasCrashed(self):
    return (self.exit_code < 0 and
            self.exit_code != -signal.SIGABRT)


def Execute(args, cwd, timeout=None):
  popen_args = [c for c in args if c != ""]
  kwargs = {}
  if PYTHON3:
    kwargs['encoding'] = 'utf-8'
  try:
    process = subprocess.Popen(
      args=popen_args,
      stdout=subprocess.PIPE,
      stderr=subprocess.PIPE,
      cwd=cwd,
      **kwargs
    )
  except Exception as e:
    sys.stderr.write("Error executing: %s\n" % popen_args)
    raise e

  timeout_event = Event()

  def kill_process():
    timeout_event.set()
    try:
      process.kill()
    except OSError:
      sys.stderr.write('Error: Process %s already ended.\n' % process.pid)

  timer = Timer(timeout, kill_process)
  timer.start()
  stdout, _ = process.communicate()
  timer.cancel()

  if timeout_event.is_set():
    raise PassException('# V8 correctness - T-I-M-E-O-U-T')

  return Output(
      process.returncode,
      stdout,
      process.pid,
  )
