#!/usr/bin/python

import argparse
import urllib2
import json
from jinja2 import Environment, Template, FileSystemLoader

from app.properties import Properties
from app.marathon import MarathonTaskInfo

def to_set(param, sep=','):
  return set(param.split(sep))

def http(url):
  print "Fetching from %s " % url
  req = urllib2.Request(url)
  response = urllib2.urlopen(req)
  return json.loads(response.read())

def fetch_tasks(marathon_uri, app_id):
  app = http(marathon_uri+"/v2/apps/"+app_id)
  app_tasks = app["app"]["tasks"]
  tasks = map(lambda task: MarathonTaskInfo(task["host"], task["ports"]), app_tasks)
  return sorted(tasks, key=lambda task: task.name())

def tasks_for(marathon_url, apps):
  response = {}
  for app in apps:
    try:
      response[app] = fetch_tasks(marathon_url, app)
    except:
      print "Failed fetching task info for %s" % (app)
      pass
  return response

def render(template, out_file, variables):
  env = Environment(loader=FileSystemLoader('templates'))
  app_name = template.split(".")[0]
  properties = Properties.load("conf/"+app_name+".properties")

  template = env.get_template(template)
  rendered_template = template.stream(j2 = variables, props = {app_name : properties})
  rendered_template.dump(out_file)

class MarathonTemplate(object):
  def __init__(self, marathon, apps):
    pass

if __name__ == '__main__':
  argumentParser = argparse.ArgumentParser(prog='marathon_template', description='Script that\'s used to generate ha_proxy config file from marathon')
  argumentParser.add_argument('-m', '--marathon', help='Marathon URI', required=True)
  argumentParser.add_argument('-a', '--app_name', type=to_set, help='App name for which haproxy config needs to be generated', required=True)
  argumentParser.add_argument('-t', '--template_file', help='Template file which on which rendering would be done', required=True)
  argumentParser.add_argument('-o', '--out_file', help='Output file', required=True)

  args = argumentParser.parse_args()

  response = tasks_for(args.marathon, args.app_name)
  render(args.template_file, args.out_file, response)