#!/usr/bin/env python
#
# Copyright 2018 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.
"""Example script for getting the Net log."""

from __future__ import print_function

import argparse
import select
import socket
import sys
import time
import threading


class NetLog:
  """
  Uses a non-blocking socket to establish a connection with a
  NetLog and then will allow the log to be fetched.
  """

  def __init__(self, host, port):
    self.host = host
    self.port = port
    self.server_socket = None

  def FetchLog(self):
    if not self.server_socket:
      self.server_socket = self._TryCreateSocketConnection()
      if not self.server_socket:
        return None
    try:
      log = self._TryRead()
      if log is None:
        self.server_socket = None
      else:
        return log
    except socket.error as e:
      print(__file__ + ': Socket error while reading log:' \
            + str(e.errno) + ' - ' + str(e.strerror))
      self.server_socket = None
      return None

  # Private members
  def _TryRead(self):
    try:
      ready_list, _, _ = select.select([self.server_socket], [], [])
      if not ready_list:
        return ''
      result = self.server_socket.recv(1024).decode('utf-8')
      # An empty string is a flag that the connection has closed.
      if len(result) == 0:
        return None
      return result
    except socket.error as e:
      if e.errno == 10035:  # Data not ready yet.
        return ''
      else:
        raise

  def _TryCreateSocketConnection(self):
    try:
      print('Waiting for connection to ' + str(self.host) + ':' +
            str(self.port))

      server_socket = socket.create_connection((self.host, self.port),
                                               timeout=1)
      server_socket.setblocking(0)
      return server_socket
    except socket.timeout:
      return None
    except socket.error as err:
      print('Error while trying to create socket: ' + str(err))
      return None


class NetLogThread(threading.Thread):
  """Threaded version of NetLog"""

  def __init__(self, host, port):
    super(NetLogThread, self).__init__()
    self.web_log = NetLog(host, port)
    self.alive = True
    self.log_mutex = threading.Lock()
    self.log = []
    self.start()

  def join(self):
    self.alive = False
    return super(NetLogThread, self).join()

  def GetLog(self):
    with self.log_mutex:
      log_copy = self.log
      self.log = []
      return ''.join(log_copy)

  def run(self):
    while self.alive:
      new_log = self.web_log.FetchLog()
      if new_log:
        with self.log_mutex:
          self.log.extend(new_log)


def TestNetLog(host, port):
  print('Started...')
  web_log = NetLog(host, port)

  while True:
    log = web_log.FetchLog()
    if log:
      print(log, end='')
    time.sleep(.1)


def main(argv):
  parser = argparse.ArgumentParser(description='Connects to the weblog.')
  parser.add_argument(
      '--host',
      type=str,
      required=False,
      default='localhost',
      help='Example localhost or 1.2.3.4')
  parser.add_argument('--port', type=int, required=False, default='49353')
  args = parser.parse_args(argv)

  thread = NetLogThread(args.host, args.port)

  try:
    while True:
      print(thread.GetLog(), end='')
      time.sleep(.1)
  except KeyboardInterrupt:
    print('\nUser canceled.')
    pass

  print('Waiting to join...')
  thread.join()
  return 0


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
