#!/usr/bin/env python
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import errno
import json
import os
import re
import subprocess


class Host(object):
  """Represents a local system with a build of Fuchsia.

    This class abstracts the details of various repository, tool, and build
    paths, as well as details about the host architecture and platform.

    Attributes:
      fuzzers:   The fuzzer binaries available in the current Fuchsia image
      build_dir: The build output directory, if present.
  """

  # Convenience file descriptor for silencing subprocess output
  DEVNULL = open(os.devnull, 'w')

  class ConfigError(RuntimeError):
    """Indicates the host is not configured for building Fuchsia."""
    pass

  @classmethod
  def from_build(cls):
    """Uses a local build directory to configure a Host object from it."""
    host = Host()
    host.set_build_dir(host.find_build_dir())
    return host

  @classmethod
  def join(cls, *segments):
    """Creates a source tree path."""
    fuchsia = os.getenv('FUCHSIA_DIR')
    if not fuchsia:
      raise Host.ConfigError('Unable to find FUCHSIA_DIR; have you `fx set`?')
    return os.path.join(fuchsia, *segments)

  def __init__(self):
    self._ids = None
    self._llvm_symbolizer = None
    self._symbolizer_exec = None
    self._platform = None
    self._zxtools = None
    self.fuzzers = []
    self.build_dir = None

  @classmethod
  def find_build_dir(self):
    """Examines the source tree to locate a build directory."""
    build_dir = Host.join('.fx-build-dir')
    if not os.path.exists(build_dir):
      raise Host.ConfigError('Unable to find .fx-build-dir; have you `fx set`?')
    with open(build_dir, 'r') as f:
      return Host.join(f.read().strip())

  def set_build_ids(self, build_ids):
    """Sets the build IDs used to symbolize logs."""
    if not os.path.exists(build_ids):
      raise Host.ConfigError('Unable to find builds IDs.')
    self._ids = build_ids

  def set_zxtools(self, zxtools):
    """Sets the location of the Zircon host tools directory."""
    if not os.path.isdir(zxtools):
      raise Host.ConfigError('Unable to find Zircon host tools.')
    self._zxtools = zxtools

  def set_platform(self, platform):
    """Sets the platform used for host OS-specific behavior."""
    if not os.path.isdir(Host.join('buildtools', platform)):
      raise Host.ConfigError('Unsupported host platform: ' + platform)
    self._platform = platform

  def set_symbolizer(self, executable, symbolizer):
    """Sets the paths to both the wrapper and LLVM symbolizers."""
    if not os.path.exists(executable) or not os.access(executable, os.X_OK):
      raise Host.ConfigError('Invalid symbolize binary: ' + executable)
    if not os.path.exists(symbolizer) or not os.access(symbolizer, os.X_OK):
      raise Host.ConfigError('Invalid LLVM symbolizer: ' + symbolizer)
    self._symbolizer_exec = executable
    self._llvm_symbolizer = symbolizer

  def set_fuzzers_json(self, json_file):
    """Sets the path to the build file with fuzzer metadata."""
    if not os.path.exists(json_file):
      raise Host.ConfigError('Unable to find list of fuzzers.')
    self.fuzzers = []
    with open(json_file) as f:
      fuzz_specs = json.load(f)
    for fuzz_spec in fuzz_specs:
      pkg = fuzz_spec['fuzzers_package']
      for tgt in fuzz_spec['fuzzers']:
        self.fuzzers.append((pkg, tgt))

  def set_build_dir(self, build_dir):
    """Configure the host using data from a build directory."""
    self.set_build_ids(Host.join(build_dir, 'ids.txt'))
    self.set_zxtools(Host.join(build_dir + '.zircon', 'tools'))
    platform = 'mac-x64' if os.uname()[0] == 'Darwin' else 'linux-x64'
    self.set_platform(platform)
    self.set_symbolizer(
        Host.join('zircon', 'prebuilt', 'downloads', 'symbolize'),
        Host.join('buildtools', platform, 'clang', 'bin', 'llvm-symbolizer'))
    json_file = Host.join(build_dir, 'fuzzers.json')
    # fuzzers.json isn't emitted in release builds
    if os.path.exists(json_file):
      self.set_fuzzers_json(json_file)
    self.build_dir = build_dir

  def zircon_tool(self, cmd, logfile=None):
    """Executes a tool found in the ZIRCON_BUILD_DIR."""
    if not self._zxtools:
      raise Host.ConfigError('Zircon host tools unavailable.')
    if not os.path.isabs(cmd[0]):
      cmd[0] = os.path.join(self._zxtools, cmd[0])
    if not os.path.exists(cmd[0]):
      raise Host.ConfigError('Unable to find Zircon host tool: ' + cmd[0])
    if logfile:
      subprocess.Popen(cmd, stdout=logfile, stderr=subprocess.STDOUT)
    else:
      return subprocess.check_output(cmd, stderr=Host.DEVNULL).strip()

  def killall(self, process):
    """ Invokes killall on the process name."""
    subprocess.call(
        ['killall', process], stdout=Host.DEVNULL, stderr=Host.DEVNULL)

  def symbolize(self, log_in, log_out):
    """Symbolizes backtraces in a log file using the current build."""
    if not self._symbolizer_exec:
      raise Host.ConfigError('Symbolizer executable not set.')
    if not self._ids:
      raise Host.ConfigError('Build IDs not set.')
    if not self._llvm_symbolizer:
      raise Host.ConfigError('LLVM symbolizer not set.')
    subprocess.check_call(
        [
            self._symbolizer_exec, '-ids-rel', '-ids', self._ids,
            '-llvm-symbolizer', self._llvm_symbolizer
        ],
        stdin=log_in,
        stdout=log_out)

  def notify_user(self, title, body):
    """Displays a message to the user in a platform-specific way"""
    if not self._platform:
      return
    elif self._platform == 'mac-x64':
      subprocess.call([
          'osascript', '-e',
          'display notification "' + body + '" with title "' + title + '"'
      ])
    elif subprocess.call(
        ['which', 'notify-send'], stdout=Host.DEVNULL,
        stderr=Host.DEVNULL) == 0:
      subprocess.call(
          ['notify-send', title, body],
          stdout=Host.DEVNULL,
          stderr=Host.DEVNULL)
    else:
      subprocess.call(
          ['wall', title + '; ' + body],
          stdout=Host.DEVNULL,
          stderr=Host.DEVNULL)

  def snapshot(self):
    integration = Host.join('integration')
    if not os.path.isdir(integration):
      raise Host.ConfigError('Missing integration repo.')
    return subprocess.check_output(
        ['git', 'rev-parse', 'HEAD'], stderr=Host.DEVNULL,
        cwd=integration).strip()
