#!/usr/bin/env python
# Copyright 2016 The Chromium 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 datetime
import fnmatch
import logging
import os
import os.path
import queue as Queue
import sublime
import sublime_plugin
import subprocess
import sys
import tempfile
import threading
import time

# Path to the version of ninja checked in into Chrome.
rel_path_to_ninja = os.path.join('third_party', 'depot_tools', 'ninja')


class PrintOutputCommand(sublime_plugin.TextCommand):
    def run(self, edit, **args):
        self.view.set_read_only(False)
        self.view.insert(edit, self.view.size(), args['text'])
        self.view.show(self.view.size())
        self.view.set_read_only(True)


class CompileCurrentFile(sublime_plugin.TextCommand):
  # static thread so that we don't try to run more than once at a time.
  thread = None
  lock = threading.Lock()

  def __init__(self, args):
    super(CompileCurrentFile, self).__init__(args)
    self.thread_id = threading.current_thread().ident
    self.text_to_draw = ""
    self.interrupted = False

  def description(self):
    return ("Compiles the file in the current view using Ninja, so all that "
            "this file and it's project depends on will be built first\n"
            "Note that this command is a toggle so invoking it while it runs "
            "will interrupt it.")

  def draw_panel_text(self):
    """Draw in the output.exec panel the text accumulated in self.text_to_draw.

    This must be called from the main UI thread (e.g., using set_timeout).
    """
    assert self.thread_id == threading.current_thread().ident
    logging.debug("draw_panel_text called.")
    self.lock.acquire()
    text_to_draw = self.text_to_draw
    self.text_to_draw = ""
    self.lock.release()

    if len(text_to_draw):
      self.output_panel.run_command('print_output', {'text': text_to_draw})
      self.view.window().run_command("show_panel", {"panel": "output.exec"})
      logging.debug("Added text:\n%s.", text_to_draw)

  def update_panel_text(self, text_to_draw):
    self.lock.acquire()
    self.text_to_draw += text_to_draw
    self.lock.release()
    sublime.set_timeout(self.draw_panel_text, 0)

  def execute_command(self, command, cwd):
    """Execute the provided command and send ouput to panel.

    Because the implementation of subprocess can deadlock on windows, we use
    a Queue that we write to from another thread to avoid blocking on IO.

    Args:
      command: A list containing the command to execute and it's arguments.
    Returns:
      The exit code of the process running the command or,
       1 if we got interrupted.
      -1 if we couldn't start the process
      -2 if we couldn't poll the running process
    """
    logging.debug("Running command: %s", command)

    def EnqueueOutput(out, queue):
      """Read all the output from the given handle and insert it into the queue.

      Args:
        queue: The Queue object to write to.
      """
      while True:
        # This readline will block until there is either new input or the handle
        # is closed. Readline will only return None once the handle is close, so
        # even if the output is being produced slowly, this function won't exit
        # early.
        # The potential dealock here is acceptable because this isn't run on the
        # main thread.
        data = out.readline()
        if not data:
          break
        queue.put(data, block=True)
      out.close()

    try:
      os.chdir(cwd)
      proc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True,
                              stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
    except OSError as e:
      logging.exception('Execution of %s raised exception: %s.', (command, e))
      return -1

    # Use a Queue to pass the text from the reading thread to this one.
    stdout_queue = Queue.Queue()
    stdout_thread = threading.Thread(target=EnqueueOutput,
                                     args=(proc.stdout, stdout_queue))
    stdout_thread.daemon = True  # Ensure this exits if the parent dies
    stdout_thread.start()

    # We use the self.interrupted flag to stop this thread.
    while not self.interrupted:
      try:
        exit_code = proc.poll()
      except OSError as e:
        logging.exception('Polling execution of %s raised exception: %s.',
                          command, e)
        return -2

      # Try to read output content from the queue
      current_content = ""
      for _ in range(2048):
        try:
          current_content += stdout_queue.get_nowait().decode('utf-8')
        except Queue.Empty:
          break
      self.update_panel_text(current_content)
      current_content = ""
      if exit_code is not None:
        while stdout_thread.isAlive() or not stdout_queue.empty():
          try:
            current_content += stdout_queue.get(
                               block=True, timeout=1).decode('utf-8')
          except Queue.Empty:
            # Queue could still potentially contain more input later.
            pass
        time_length = datetime.datetime.now() - self.start_time
        self.update_panel_text("%s\nDone!\n(%s seconds)" %
                               (current_content, time_length.seconds))
        return exit_code
      # We sleep a little to give the child process a chance to move forward
      # before we poll it again.
      time.sleep(0.1)

    # If we get here, it's because we were interrupted, kill the process.
    proc.terminate()
    return 1

  def run(self, edit, target_build):
    """The method called by Sublime Text to execute our command.

    Note that this command is a toggle, so if the thread is are already running,
    calling run will interrupt it.

    Args:
      edit: Sumblime Text specific edit brace.
      target_build: Release/Debug/Other... Used for the subfolder of out.
    """
    # There can only be one... If we are running, interrupt and return.
    if self.thread and self.thread.is_alive():
      self.interrupted = True
      self.thread.join(5.0)
      self.update_panel_text("\n\nInterrupted current command:\n%s\n" % command)
      self.thread = None
      return

    # It's nice to display how long it took to build.
    self.start_time = datetime.datetime.now()
    # Output our results in the same panel as a regular build.
    self.output_panel = self.view.window().get_output_panel("exec")
    self.output_panel.set_read_only(True)
    self.view.window().run_command("show_panel", {"panel": "output.exec"})
    # TODO(mad): Not sure if the project folder is always the first one... ???
    project_folder = self.view.window().folders()[0]
    self.update_panel_text("Compiling current file %s\n" %
                           self.view.file_name())
    # The file must be somewhere under the project folder...
    if (project_folder.lower() !=
        self.view.file_name()[:len(project_folder)].lower()):
      self.update_panel_text(
          "ERROR: File %s is not in current project folder %s\n" %
              (self.view.file_name(), project_folder))
    else:
      output_dir = os.path.join(project_folder, 'out', target_build)
      source_relative_path = os.path.relpath(self.view.file_name(),
                                             output_dir)
      # On Windows the caret character needs to be escaped as it's an escape
      # character.
      carets = '^'
      if sys.platform.startswith('win'):
        carets = '^^'
      command = [
          os.path.join(project_folder, rel_path_to_ninja), "-C",
          os.path.join(project_folder, 'out', target_build),
          source_relative_path + carets]
      self.update_panel_text(' '.join(command) + '\n')
      self.interrupted = False
      self.thread = threading.Thread(target=self.execute_command,
                                     kwargs={"command":command,
                                             "cwd": output_dir})
      self.thread.start()

    time_length = datetime.datetime.now() - self.start_time
    logging.debug("Took %s seconds on UI thread to startup",
                  time_length.seconds)
    self.view.window().focus_view(self.view)
