#!/usr/bin/python
# This is python 2.7 on macOS 10.12.

from __future__ import print_function

import api_pb2
import argparse
import logging
import sys
import thread
import time
import traceback
import websocket

callbacks = []

def list_sessions(ws, argv):
    def callback(response):
      print(str(response))
      ws.close()
    request = api_pb2.Request()
    request.list_sessions_request.SetInParent()
    SendRPC(ws, request, callback)

def send_text(ws, argv):
  def callback(response):
    print(str(response))
    ws.close()
  request = api_pb2.Request()
  request.send_text_request.text = argv[2]
  SendRPC(ws, request, callback)

def create_tab(ws, argv):
  def callback(response):
    print(str(response))
    ws.close()
  parser = argparse.ArgumentParser(description='Create a tab or window')
  parser.add_argument('--profile', type=str, nargs='?', help='Profile name')
  parser.add_argument('--window', type=str, nargs='?', help='Window ID')
  parser.add_argument('--index', type=int, nargs='?', help='Desired tab index')
  parser.add_argument('--command', type=str, nargs='?', help='Command')
  args = parser.parse_args(argv[2:])

  request = api_pb2.Request()
  request.create_tab_request.SetInParent()
  if args.profile is not None:
    request.create_tab_request.profile_name = args.profile
  if args.window is not None:
    request.create_tab_request.window_id = args.window
  if args.index is not None:
    request.create_tab_request.tab_index = args.index
  if args.command is not None:
    request.create_tab_request.command = args.command
  SendRPC(ws, request, callback)

def split_pane(ws, argv):
  def callback(response):
    print(str(response))
    ws.close()
  parser = argparse.ArgumentParser(description='Split a pane')
  parser.add_argument('--session', type=str, nargs='?', help='Session ID')
  parser.add_argument('--vertical', action='store_true', help='Split vertically?', default=False)
  parser.add_argument('--before', action='store_true', help='Spilt left or above target', default=False)
  parser.add_argument('--profile', type=str, nargs='?', help='Profile name')
  args = parser.parse_args(argv[2:])

  request = api_pb2.Request()
  request.split_pane_request.SetInParent()
  if args.session is not None:
    request.split_pane_request.session_id = args.session
  if args.vertical is None:
    request.split_pane_request.split_direction = api_pb2.SplitPaneRequest.VERTICAL
  else:
    request.split_pane_request.split_direction = api_pb2.SplitPaneRequest.HORIZONTAL;
  if args.before is None:
    request.split_pane_request.before = False
  else:
    request.split_pane_request.before = args.before
  if args.profile is not None:
    request.split_pane_request.profile_name = args.profile
  SendRPC(ws, request, callback)

def handle_location_change_notification(location_change_notification):
    print("Location changed")
    print(str(location_change_notification))

def SendRPC(ws, message, callback):
    print(message)
    ws.send(message.SerializeToString(), opcode=websocket.ABNF.OPCODE_BINARY)
    callbacks.append(callback)

def handle_notification(notification):
    if notification.HasField('location_change_notification'):
      handle_location_change_notification(notification.location_change_notification)

def handle_notification_response(response):
  if not response.HasField('notification_response'):
    print("Malformed notification response")
    print(str(response))
    return
  if response.notification_response.status != api_pb2.NotificationResponse.OK:
    print("Bad status in notification response")
    print(str(response))
    return
  print("Notifcation response ok")

def on_message(ws, message):
    response = api_pb2.Response()
    response.ParseFromString(message)
    if response.HasField('notification'):
      handle_notification(response.notification)
    else:
      global callbacks
      callback = callbacks[0]
      del callbacks[0]
      callback(response)

def on_error(ws, error):
    print("Error: " + str(error))

def on_close(ws):
    print("Connection closed")

def main(argv):
    logging.basicConfig()

    commands = { "list-sessions": list_sessions,
                 "send-text": send_text,
                 "create-tab": create_tab,
                 "split-pane": split_pane }
    if len(argv) < 2:
      print("Not enough arguments")
      return -1
    if argv[1] not in commands:
      print("Unrecognized command " + argv[1])
      return -2

    def on_open(ws):
      try:
        f = commands[argv[1]]
        f(ws, argv)
      except Exception as e:
        traceback.print_exc()

    #websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://localhost:1912/",
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close,
                              subprotocols = [ 'api.iterm2.com' ])
    ws.on_open = on_open
    ws.run_forever()

if __name__ == "__main__":
    main(sys.argv)

