#!/usr/bin/env python2

# Copyright 2017 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Send a link to a process running LinkReceiver.

If a Starboard implementation instantiates
starboard::shared::starboard::LinkReceiver, then it will write a file containing
the port to the configured temporary directory. This script finds that file and
sends the specified link to that service. It is up to the application to
interpret that link content.

Note that LinkReceiver generally runs on the loopback interface, so this script
should be run from the same device running the application.

"""

import argparse
from contextlib import closing
import logging
import os
import socket
import sys
import tempfile
import textwrap
import time


def _Uncase(text):
  return text.upper().lower()


def _GetPids(executable):
  if sys.platform in ('win32', 'cygwin'):
    raise NotImplementedError('Implement me for Windows!')
  elif sys.platform.startswith('linux') or sys.platform == 'darwin':
    pids = []
    executable = _Uncase(executable)
    for pid in os.listdir('/proc'):
      if pid == 'curproc':
        continue

      pid_path = '/proc/' + pid
      if not os.path.isdir(pid_path):
        continue

      try:
        cmdline_path = os.path.join(pid_path, 'cmdline')
        with open(cmdline_path, mode='rb') as cmdline:
          content = cmdline.read().decode().split('\x00')
      except IOError:
        continue

      if os.path.basename(_Uncase(content[0])).startswith(executable):
        pids += [pid]
    return pids


def _FindTemporaryFile(prefix, suffix):
  directory = tempfile.gettempdir()
  for entry in os.listdir(directory):
    caseless_entry = _Uncase(entry)
    if caseless_entry.startswith(prefix) and caseless_entry.endswith(suffix):
      return os.path.join(directory, entry)

  return None


def _ConnectWithRetry(s, port, num_attempts):
  for attempt in range(num_attempts):
    if attempt > 0:
      time.sleep(1)
    try:
      s.connect(('localhost', port))
      return True
    except (RuntimeError, IOError):
      logging.error('Could not connect to port %d, attempt %d / %d', port,
                    attempt, num_attempts)
  return False


def SendLink(executable, link, connection_attempts=1):
  """Sends a link to the process starting with the given executable name."""

  pids = _GetPids(executable)

  if not pids:
    logging.error('No PIDs found for %s', executable)
    return 1

  if len(pids) > 1:
    logging.error('Multiple PIDs found for %s: %s', executable, pids)
    return 1

  pid = pids[0]
  temporary_directory = _FindTemporaryFile(_Uncase(executable), _Uncase(pid))
  if not os.path.isdir(temporary_directory):
    logging.error('Not a directory: %s', temporary_directory)
    return 1

  port_file_path = os.path.join(temporary_directory, 'link_receiver_port')
  if not os.path.isfile(port_file_path):
    logging.error('Not a file: %s', port_file_path)
    return 1

  try:
    with open(port_file_path, mode='rb') as port_file:
      port = int(port_file.read().decode())
  except IOError:
    logging.exception('Could not open port file: %s', port_file_path)
    return 1

  try:
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
      if not _ConnectWithRetry(s, port, connection_attempts):
        logging.exception('Could not connect to port: %d', port)
        return 1
      terminated_link = (link + '\x00').encode()
      bytes_sent = 0
      while bytes_sent < len(terminated_link):
        sent = s.send(terminated_link[bytes_sent:])
        if sent == 0:
          raise RuntimeError('Connection terminated by remote host.')
        bytes_sent += sent
  except (RuntimeError, IOError):
    logging.exception('Could not connect to port: %d', port)
    return 1

  logging.info('Link "%s" sent to %s at pid %s on port %d.', link, executable,
               pid, port)

  return 0


def main():
  parser = argparse.ArgumentParser(
      formatter_class=argparse.ArgumentDefaultsHelpFormatter,
      description=textwrap.dedent(__doc__))
  parser.add_argument(
      'executable',
      type=str,
      help='Name of the running executable to send a link to.')
  parser.add_argument(
      'link', type=str, help='The link content to send to the executable.')
  arguments = parser.parse_args()
  return SendLink(arguments.executable, arguments.link)


if __name__ == '__main__':
  logging.basicConfig(level=logging.INFO, format='[%(levelname)5s] %(message)s')
  sys.exit(main())
