#!/usr/bin/env vpython3
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import contextlib
import datetime
import pathlib
import unittest
import os
import signal
import socket
import subprocess
import sys
import tempfile
import time

import fast_local_dev_server as server

sys.path.append(os.path.join(os.path.dirname(__file__), 'gyp'))
from util import server_utils


class RegexTest(unittest.TestCase):

  def testBuildIdRegex(self):
    self.assertRegex(server.FIRST_LOG_LINE.format(build_id='abc', outdir='PWD'),
                     server.BUILD_ID_RE)


def sendMessage(message):
  with contextlib.closing(socket.socket(socket.AF_UNIX)) as sock:
    sock.settimeout(1)
    sock.connect(server_utils.SOCKET_ADDRESS)
    server_utils.SendMessage(sock, message)


def pollServer():
  try:
    sendMessage({'message_type': server_utils.POLL_HEARTBEAT})
    return True
  except ConnectionRefusedError:
    return False


def shouldSkip():
  if os.environ.get('ALLOW_EXTERNAL_BUILD_SERVER', None):
    return False
  return pollServer()


def callServer(args, check=True):
  return subprocess.run([str(server_utils.SERVER_SCRIPT.absolute())] + args,
                        cwd=pathlib.Path(__file__).parent,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT,
                        check=check,
                        text=True,
                        timeout=3)


@contextlib.contextmanager
def blockingFifo(fifo_path='/tmp/.fast_local_dev_server_test.fifo'):
  fifo_path = pathlib.Path(fifo_path)
  try:
    if not fifo_path.exists():
      os.mkfifo(fifo_path)
    yield fifo_path
  finally:
    # Write to the fifo nonblocking to unblock other end.
    try:
      pipe = os.open(fifo_path, os.O_WRONLY | os.O_NONBLOCK)
      os.write(pipe, b'')
      os.close(pipe)
    except OSError:
      # Can't open non-blocking an unconnected pipe for writing.
      pass
    fifo_path.unlink(missing_ok=True)


class ServerStartedTest(unittest.TestCase):
  build_id_counter = 0
  task_name_counter = 0

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self._tty_path = None
    self._build_id = None

  def setUp(self):
    if shouldSkip():
      self.skipTest("Cannot run test when server already running.")
    self._process = subprocess.Popen(
        [server_utils.SERVER_SCRIPT.absolute(), '--exit-on-idle', '--quiet'],
        start_new_session=True,
        cwd=pathlib.Path(__file__).parent,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True)
    # pylint: disable=unused-variable
    for attempt in range(5):
      if pollServer():
        break
      time.sleep(0.05)

  def tearDown(self):
    self._process.terminate()
    stdout, _ = self._process.communicate()
    if stdout != '':
      self.fail(f'build server should be silent but it output:\n{stdout}')

  @contextlib.contextmanager
  def _register_build(self):
    with tempfile.NamedTemporaryFile() as f:
      build_id = f'BUILD_ID_{ServerStartedTest.build_id_counter}'
      os.environ['AUTONINJA_BUILD_ID'] = build_id
      os.environ['AUTONINJA_STDOUT_NAME'] = f.name
      ServerStartedTest.build_id_counter += 1
      build_proc = subprocess.Popen(
          [sys.executable, '-c', 'import time; time.sleep(100)'])
      callServer(
          ['--register-build', build_id, '--builder-pid',
           str(build_proc.pid)])
      self._tty_path = f.name
      self._build_id = build_id
      try:
        yield
      finally:
        self._tty_path = None
        self._build_id = None
        del os.environ['AUTONINJA_BUILD_ID']
        del os.environ['AUTONINJA_STDOUT_NAME']
        build_proc.kill()
        build_proc.wait()

  def sendTask(self, cmd, stamp_path=None):
    if stamp_path:
      _stamp_file = pathlib.Path(stamp_path)
    else:
      _stamp_file = pathlib.Path('/tmp/.test.stamp')
    _stamp_file.touch()

    name_prefix = f'{self._build_id}-{ServerStartedTest.task_name_counter}'
    sendMessage({
        'name': f'{name_prefix}: {" ".join(cmd)}',
        'message_type': server_utils.ADD_TASK,
        'cmd': cmd,
        # So that logfiles do not clutter cwd.
        'cwd': '/tmp/',
        'build_id': self._build_id,
        'stamp_file': _stamp_file.name,
    })
    ServerStartedTest.task_name_counter += 1

  def getTtyContents(self):
    return pathlib.Path(self._tty_path).read_text()

  def getBuildInfo(self):
    build_info = server.query_build_info(self._build_id)['builds'][0]
    pending_tasks = build_info['pending_tasks']
    completed_tasks = build_info['completed_tasks']
    return pending_tasks, completed_tasks

  def waitForTasksDone(self, timeout_seconds=3):
    timeout_duration = datetime.timedelta(seconds=timeout_seconds)
    start_time = datetime.datetime.now()
    while True:
      pending_tasks, completed_tasks = self.getBuildInfo()

      if completed_tasks > 0 and pending_tasks == 0:
        return

      current_time = datetime.datetime.now()
      duration = current_time - start_time
      if duration > timeout_duration:
        raise TimeoutError('Timed out waiting for pending tasks ' +
                           f'[{pending_tasks}/{pending_tasks+completed_tasks}]')
      time.sleep(0.1)

  def testRunsQuietTask(self):
    with self._register_build():
      self.sendTask(['true'])
      self.waitForTasksDone()
      self.assertEqual(self.getTtyContents(), '')

  def testRunsNoisyTask(self):
    with self._register_build():
      self.sendTask(['echo', 'some_output'])
      self.waitForTasksDone()
      tty_contents = self.getTtyContents()
      self.assertIn('some_output', tty_contents)

  def testStampFileDeletedOnFailedTask(self):
    with self._register_build():
      stamp_file = pathlib.Path('/tmp/.failed_task.stamp')
      self.sendTask(['echo', 'some_output'], stamp_path=stamp_file)
      self.waitForTasksDone()
      self.assertFalse(stamp_file.exists())

  def testStampFileNotDeletedOnSuccess(self):
    with self._register_build():
      stamp_file = pathlib.Path('/tmp/.successful_task.stamp')
      self.sendTask(['true'], stamp_path=stamp_file)
      self.waitForTasksDone()
      self.assertTrue(stamp_file.exists())

  def testWaitForBuildServerCall(self):
    with self._register_build():
      callServer(['--wait-for-build', self._build_id])
      self.assertEqual(self.getTtyContents(), '')

  def testWaitForIdleServerCall(self):
    with self._register_build():
      self.sendTask(['true'])
      proc_result = callServer(['--wait-for-idle'])
      self.assertIn('All', proc_result.stdout)
      self.assertEqual('', self.getTtyContents())

  def testCancelBuildServerCall(self):
    with self._register_build():
      callServer(['--cancel-build', self._build_id])
      self.assertEqual(self.getTtyContents(), '')

  def testBuildStatusServerCall(self):
    with self._register_build():
      proc_result = callServer(['--print-status', self._build_id])
      self.assertEqual(proc_result.stdout, '')

      proc_result = callServer(['--print-status-all'])
      self.assertIn(self._build_id, proc_result.stdout)

      self.sendTask(['true'])
      self.waitForTasksDone()

      proc_result = callServer(['--print-status', self._build_id])
      self.assertEqual('', proc_result.stdout)

      proc_result = callServer(['--print-status-all'])
      self.assertIn('has 1 registered build', proc_result.stdout)
      self.assertIn('1/1', proc_result.stdout)

      with blockingFifo() as fifo_path:
        # cat gets stuck until we open the other end of the fifo.
        self.sendTask(['cat', str(fifo_path)])
        proc_result = callServer(['--print-status', self._build_id])
        self.assertIn('is still 1 static analysis job', proc_result.stdout)
        self.assertIn('--wait-for-idle', proc_result.stdout)
        proc_result = callServer(['--print-status-all'])
        self.assertIn('1/2', proc_result.stdout)

      self.waitForTasksDone()
      callServer(['--cancel-build', self._build_id])
      self.waitForTasksDone()
      proc_result = callServer(['--print-status', self._build_id])
      self.assertEqual('', proc_result.stdout)

    proc_result = callServer(['--print-status-all'])
    self.assertIn('Main build completed', proc_result.stdout)

  def testServerCancelsRunningTasks(self):
    output_stamp = pathlib.Path('/tmp/.deleteme.stamp')
    with blockingFifo() as fifo_path:
      self.assertFalse(output_stamp.exists())
      # dd blocks on fifo so task never finishes inside with block.
      with self._register_build():
        self.sendTask(['dd', f'if={str(fifo_path)}', f'of={str(output_stamp)}'])
        callServer(['--cancel-build', self._build_id])
        self.waitForTasksDone()
    self.assertFalse(output_stamp.exists())

  def testKeyboardInterrupt(self):
    os.kill(self._process.pid, signal.SIGINT)
    self._process.wait(timeout=1)


class ServerNotStartedTest(unittest.TestCase):

  def setUp(self):
    if pollServer():
      self.skipTest("Cannot run test when server already running.")

  def testWaitForBuildServerCall(self):
    proc_result = callServer(['--wait-for-build', 'invalid-build-id'])
    self.assertIn('No server running', proc_result.stdout)

  def testBuildStatusServerCall(self):
    proc_result = callServer(['--print-status-all'])
    self.assertIn('No server running', proc_result.stdout)


if __name__ == '__main__':
  # Suppress logging messages.
  unittest.main(buffer=True)
