#
# 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, arg_list):
  arg_string = '\n'.join(arg_list)
  try:
    server_socket = socket.create_connection((host, port), timeout=.5)
    server_socket.sendall(arg_string)
    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,
                                                    self.arg_list)
      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:]))
