#!/usr/bin/env python

##
#
# Vaisala software source code file
#
# Copyright (c) Vaisala Oyj 2014. All rights reserved.
#
##

# This script configures the map. It executes the following steps:
# 1. Check the command line argument -url, if it is provided use that as the map URL, otherwise
#    default to /geoserver/osm/wms
# 2. Check if the application is running and accessible by visiting the health-check URL
# 3. If application is accessible, call the map view configuration URL to configure the map

from __future__ import print_function

import sys
import os
import urllib2
import urllib
import json
import cookielib
import argparse

DEFAULT_VALUE = "/wms"
COOKIE_FILE = "cookies.txt"

BASE_URL = None
HEALTH_CHECK_URL = None
LOGIN_URL = None
CONFIGURE_MAP_URL = None


def set_base_url(url):
    global BASE_URL, HEALTH_CHECK_URL, LOGIN_URL, CONFIGURE_MAP_URL
    BASE_URL = url.rstrip("/")
    HEALTH_CHECK_URL = BASE_URL + "/health"
    LOGIN_URL = BASE_URL + "/login"
    CONFIGURE_MAP_URL = BASE_URL + "/configure/map"


set_base_url("http://127.0.0.1:34080")


def e(*args, **kwargs):
    kwargs['file'] = sys.stderr
    return print(*args, **kwargs)


def application_is_healthy():
    try:
        req = urllib2.Request(HEALTH_CHECK_URL)
        handler = urllib2.urlopen(req)
        http_status_code = handler.getcode()
        if http_status_code == 200:
            return True
        else:
            e("Application health check at %s returned status code %s" % (HEALTH_CHECK_URL, http_status_code))
    except urllib2.URLError:
        e("Application not responding at %s" % HEALTH_CHECK_URL)


def login(username, password, cookies):
    try:
        handlers = [urllib2.HTTPHandler(), urllib2.HTTPCookieProcessor(cookies)]
        opener = urllib2.build_opener(*handlers)
        data = {'username': username, 'password': password}
        response = opener.open(LOGIN_URL, urllib.urlencode(data)).read()
        return json.loads(response)['xsrfToken']
    except e:
        print("Application login failed")
        raise e


def cookie_string(cookies):
    cookie_str = ""
    for cookie in cookies:
        cookie_str += cookie.name + "=" + cookie.value + ";"
    return cookie_str


def configure_map(map_url, xsrf_token, cookies):
    try:
        data = {'url': map_url, 'token': xsrf_token}
        headers = dict()
        headers['Cookie'] = cookie_string(cookies)
        request = urllib2.Request(CONFIGURE_MAP_URL, None, headers)
        response = urllib2.urlopen(request, urllib.urlencode(data), 60)
        status_code = response.getcode()
        layer_count = 0
        if status_code == 200:
            for layer in json.loads(response.read()):
                layer_count += 1
                e("Configured layer %s" % layer['name'])
        if layer_count == 0:
            e("Map configuration failed: no layers configured")
    except e:
        print("Map configuration failed")
        raise e


def cleanup():
    if os.path.isfile(COOKIE_FILE):
        os.remove(COOKIE_FILE)


def get_args():
    parser = argparse.ArgumentParser("configure-map")
    parser.add_argument("username", help="IRIS Vision admin user username")
    parser.add_argument("password", help="IRIS Vision admin user password")
    parser.add_argument("-u", "--url", help="Map URL - this is the URL of the WMS service that provides the map layers")
    parser.add_argument("-a", "--app-url", help="App URL - this is the URL of the application",
                        default="http://127.0.0.1:34080")
    return parser.parse_args()


def run():
    cookies = cookielib.LWPCookieJar(COOKIE_FILE)
    args = get_args()
    map_url = None

    if args.url:
        map_url = args.url

    if args.app_url:
        set_base_url(args.app_url)

    if map_url is None:
        e("Using default map URL: %s" % DEFAULT_VALUE)
        map_url = DEFAULT_VALUE

    if application_is_healthy():
        xsrf_token = login(args.username, args.password, cookies)
        if xsrf_token is None:
            e("Login failed")
        else:
            configure_map(map_url, xsrf_token, cookies)
    else:
        e("Application is unhealthy or not running. Is the service running?: 'service vaisala-radarsw-webapp status'.")

    cleanup()


run()
