#!/usr/bin/env python

##
#
# Vaisala software source code file
#
# Copyright (c) Vaisala Oyj 2014, 2015. All rights reserved.
#
##
from __future__ import print_function

import ConfigParser
import sys
import argparse
import filecmp
import os
import datetime
import shutil
import pwd
import grp

from os import environ as env
from os import path

SECTION = "IRIS_SOCKET_SERVER"
OPTION = "iris.socket.server.host"
IRIS_HOST_OPTION = SECTION, OPTION

CONFIG_DIRECTORY = env.get("VAISALA_RADARSW_CONFIG_DIR", '/etc/vaisala/radarsw/configuration')
CONFIG_FILE = path.join(CONFIG_DIRECTORY, 'vsoweb-override.ini')
CONFIG_FILE_RPMSAVE = CONFIG_FILE + ".rpmsave"

TEMP_FILE_NAME = "configure-iris-host.tmp"
TEMP_FILE = path.join(CONFIG_DIRECTORY, TEMP_FILE_NAME)

# Check for Python3
if sys.version_info >= (3, 0):
    read_and_write_permissions = 0o600
else:
    read_and_write_permissions = 0600


def get_args():
    parser = argparse.ArgumentParser("configure-iris-host")
    parser.add_argument("iris_host", nargs="?", help="IRIS Socket Server host name. If not specified, tries to use socket server host name from .rpmsave file")
    parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", help="Enable debug messages")
    return parser.parse_args()


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


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


def cleanup():
    if os.path.isfile(TEMP_FILE):
        dbg_msg("Remove temporary file %s" % TEMP_FILE)
        os.remove(TEMP_FILE)


def configure(iris_host):
    conf = ConfigParser.RawConfigParser()
    dbg_msg("Read configuration from %s" % CONFIG_FILE)
    conf.read(CONFIG_FILE)

    if not conf.has_section(SECTION):
        dbg_msg("Add section %s" % SECTION)
        conf.add_section(SECTION)

    dbg_msg("Set option: %s = %s" % (OPTION, iris_host))
    conf.set(SECTION, OPTION, iris_host)

    return conf


def write_to_temp_file(configuration):
    dbg_msg("Write to temporary file: %s" % TEMP_FILE)
    with open(TEMP_FILE, "wb") as temp_file:
        configuration.write(temp_file)


def back_up_current_conf():
    now = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
    backup_file = CONFIG_FILE + "." + now
    dbg_msg("Move current configuration to %s" % backup_file)
    shutil.copyfile(CONFIG_FILE, backup_file)


def move_temp_to_conf():
    dbg_msg("Move %s to %s" % (TEMP_FILE, CONFIG_FILE))
    os.rename(TEMP_FILE, CONFIG_FILE)


def assign_permissions():
    dbg_msg("Set permissions on %s" % TEMP_FILE)
    os.chown(TEMP_FILE, pwd.getpwnam("radarweb")[2], grp.getgrnam("radarsw")[2])
    os.chmod(TEMP_FILE, read_and_write_permissions)


def extract_iris_host(file_path):
    """Extracts the data source password from a file and does no error
    handling. User is expected to handle ConfigParser thrown errors.

    See https://docs.python.org/2.7/library/configparser.html#ConfigParser.Error
    for more information.
    """
    config = ConfigParser.SafeConfigParser()
    config.read(file_path)
    return config.get(*IRIS_HOST_OPTION)


def is_iris_host_set(file_path):
    try:
        iris_host = extract_iris_host(file_path)
        if iris_host is not None:
            return True
    except ConfigParser.Error:
        pass

    return False


def configure_iris_host(iris_host):
    config = configure(iris_host)
    write_to_temp_file(config)
    changed = not filecmp.cmp(TEMP_FILE, CONFIG_FILE)

    if changed:
        dbg_msg("Configuration changed")
        back_up_current_conf()
        assign_permissions()
        move_temp_to_conf()
        log("Done. IRIS Socket Server host changed to %s" % iris_host)
    else:
        log("Configuration did not change. Nothing to do.")


def main():
    cleanup()
    iris_host_arg = args.iris_host;
    current_iris_host = None
    rpmsave_iris_host = None

    if is_iris_host_set(CONFIG_FILE):
        current_iris_host = extract_iris_host(CONFIG_FILE)

    if is_iris_host_set(CONFIG_FILE_RPMSAVE):
        rpmsave_iris_host = extract_iris_host(CONFIG_FILE_RPMSAVE)

    if iris_host_arg is not None:
        if current_iris_host == iris_host_arg:
            log("IRIS Socket Server host already set to %s, exiting." % iris_host_arg)
            sys.exit(0)
        else:
            log("Setting IRIS Socket Server host to %s (passed in as an argument)" % iris_host_arg)
            configure_iris_host(iris_host_arg)
    else:
        if rpmsave_iris_host is None:
            if current_iris_host is None:
                sys.exit("Error: could not set IRIS Socket Server host - host name was not passed in as an argument nor does it exist in the .rpmsave file.")
            else:
                log("IRIS Socket Server host was not passed in as an argument nor does it exist in the .rpmsave file. Nothing to do - using the currently set IRIS Socket Server host: %s" % current_iris_host)
        else:
            if rpmsave_iris_host == current_iris_host:
                log("Nothing to do. IRIS Socket Server host found from .rpmsave matches the current IRIS Socket Server host: %s" %current_iris_host)
            else:
                log("Setting IRIS Socket Server host to %s (found from .rpmsave)" % rpmsave_iris_host)
                configure_iris_host(rpmsave_iris_host)

    cleanup()

if __name__ == '__main__':
    args = get_args()
    verbose = args.verbose
    main()









