#!/usr/bin/python

from jsonrpclib import Server
import time
import random
import json
import math
import os
from Crypto.Cipher import AES
import base64
import sys


RPC_SERVER_SECRET = sys.argv[1]

client = Server(sys.argv[2])

def generate_token(accessLevel):
    """
    Generate an RPC server token with the given access level.
    """
    token = {'timestamp': int(time.mktime(time.gmtime())), 'accesslevel': accessLevel}
    data = json.dumps(token)
    iv = os.urandom(AES.block_size)
    cipher = AES.new(RPC_SERVER_SECRET, mode=AES.MODE_CBC, IV=iv)
    data += '\x00' * (16 - (len(data)%AES.block_size))
    token = cipher.encrypt(data)
    return base64.b64encode(iv + token)

random.seed()
while True:
  try:
    res = client.ping(generate_token(700), 12345)
    if res != 12345:
      print "Is the server accessable?\n"
      exit
    
    # How many times a day is this script going to be called?
    ChecksPerDay = 60.0*24.0    # Once a minute
    InvasionsPerDay = 72.0      # How many invasions a day per district
    BaseInvasionChance = InvasionsPerDay/ChecksPerDay
    
    safeHarbor = {'Wacky Falls'}
    superDistricts = {'Nuttyboro'}
    
    
    while True:
      shards = client.listShards(generate_token(700))
      print shards
      count = 0
      for skey in shards:
        shard = shards[skey]
        if shard['invasion'] != None:
          count = count + 1
      for skey in shards:
        shard = shards[skey]
        if shard['invasion'] == None:
          if shard['name'] in superDistricts:
            typ = int(float(random.random()) * 4.0)
            suit = int(float(random.random()) * 4.0) + 4  # Bias the cogs to be big
            client.startInvasion(generate_token(700), int(skey), typ, suit, 0, 0)
            count = count + 1
            print 'Calling invasion for %s with %d,%d'%(shard['name'],typ,suit)
      if count < 3:
        for skey in shards:
          shard = shards[skey]
          if shard['invasion'] == None and not shard['name'] in safeHarbor:
            r = random.random()
            if r < BaseInvasionChance and not shard['name'] in superDistricts:
              typ = int(float(random.random()) * 4.0)
              suit = int(float(random.random()) * 8.0)
              client.startInvasion(generate_token(700), int(skey), typ, suit, 0, 0)
              print 'Calling invasion for %s with %d,%d'%(shard['name'],typ,suit)
      print "tick..(was %d)\n"%(count)
      time.sleep(60)
  except Exception, e:
    print e
  time.sleep(300)