#
# 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 Args."""

from __future__ import print_function

import argparse
import socket
import sys
import time
import threading


# Returns |True| if a connection was made and the NetArg payload was delivered.
# Example:
#  TryConnectAndSendNetArgs('1.2.3.4', '1234', ['--argument', '--switch=value'])
def TryConnectAndSendNetArgs(host, port):
  try:
    server_socket = socket.create_connection((host, port), timeout=.5)
    server_socket.close()
    return True
  except socket.timeout:
    return False
  except socket.error as e:
    print(e.errno, e.strerror)
    return False


class NetArgsThread(threading.Thread):
  """Threaded version of NetArgs"""

  def __init__(self, host, port, arg_list):
    super(NetArgsThread, self).__init__()
    assert isinstance(arg_list, list)
    self.host = host
    self.port = port
    self.args_sent = False
    self.join_called = False
    self.arg_list = arg_list
    self.mutex = threading.Lock()
    self.start()

  def join(self):
    with self.mutex:
      self.join_called = True
    return super(NetArgsThread, self).join()

  def ArgsSent(self):
    with self.mutex:
      return self.args_sent

  def run(self):
    while True:
      with self.mutex:
        if self.join_called:
          break
      connected_and_sent = TryConnectAndSendNetArgs(self.host, self.port)
      if connected_and_sent:
        with self.mutex:
          self.args_sent = True
          break


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='49355')
  parser.add_argument('--arg', type=str, required=True)
  args = parser.parse_args(argv)

  net_args_thread = NetArgsThread(args.host, args.port, [args.arg])

  while not net_args_thread.ArgsSent():
    print('Waiting to send arg ' + args.arg + ' to ' + str(args.host) + ':' +
          str(args.port) + '...')
    time.sleep(.5)

  print('Argument', args.arg, 'was sent to', \
        args.host + ':' + str(args.port))


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