#!/usr/bin/env python
##
#
# Vaisala software source code file
#
# Copyright (c) Vaisala Oyj 2014, 2015. All rights reserved.
#
##
"""
Tool for configuring PostgreSQL 9.4 to work with Vaisala Radar Software
distribution.
"""

from __future__ import print_function

import argparse
import sys
import os
import datetime
import subprocess
import logging

from os import path

PG_BIN = "/usr/pgsql-9.4/bin"
POSTGRES_DATA_DIR = "/var/lib/pgsql/9.4/data"

logger = logging.getLogger('rsw-postgresql-94-configure')

# PostgreSQL initialization
def postgres_initialized(data_dir=POSTGRES_DATA_DIR):
    try:
        subprocess.check_call(
            [path.join(PG_BIN, "postgresql94-check-db-dir"), data_dir])
    except subprocess.CalledProcessError, cpe:
        return False
    except OSError, oe:
        if "No such file or directory" in str(oe):
            logger.warn("Cannot determine whether PostgreSQL is already initialized." +
                        " Expecting it isn't.")
            return False
        else:
            raise oe
    return True

def init_postgres():
    subprocess.check_call([path.join(PG_BIN, "postgresql94-setup"),
                           "initdb", "postgresql-9.4"])

# Authentication configuration
def configure_postgres_auth(file_path, debug=False):
    command = ['rsw-postgresql-configure-auth', '--pg-hba-file', file_path]
    if debug:
        command.append("--debug")
    subprocess.check_call(command)

def configure_postgres_other_settings(file_path, debug=False):
    command = ['rsw-postgresql-configure-settings', '--postgresql-conf-file', file_path]
    if debug:
        command.append("--debug")
    subprocess.check_call(command)

def configure_postgres_service():
    SERVICE_NAME = "postgresql-9.4"
    command = ["systemctl", "enable", SERVICE_NAME]
    try:
        subprocess.check_call(command)
    except subprocess.CalledProcessError, cpe:
        logger.warn(u"Couldn't enable {} system service:".format(SERVICE_NAME))
        logger.warn(u"Command {} exited with {}.".format(command, cpe.returncode))

def main():
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("--hba-file", dest="hba_file", metavar="FILE", required=False,
                        default=path.join(POSTGRES_DATA_DIR, 'pg_hba.conf'))
    parser.add_argument("--postgresql-conf-file", dest="postgresql_conf_file",
                        metavar="FILE", required=False,
                        default=path.join(POSTGRES_DATA_DIR, 'postgresql.conf'))
    parser.add_argument("--test", dest="test", action="store_true",
                        help="Test that this tool is executable.")
    parser.add_argument("-d", "--debug", dest="debug", action="store_true",
                        help="Enable debug logging.")
    args = parser.parse_args()

    def setup_logging(debug_enabled):
        root = logging.getLogger()
        if debug_enabled:
            root.setLevel(logging.DEBUG)
        else:
            root.setLevel(logging.INFO)
        ch = logging.StreamHandler(sys.stdout)
        ch.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        ch.setFormatter(formatter)
        root.addHandler(ch)
    setup_logging(args.debug)

    if args.test:
        subprocess.check_call(['rsw-postgresql-configure-auth', '--test'])
        logger.debug("rsw-postgresql-configure-auth is callable.")
        subprocess.check_call(['rsw-postgresql-configure-settings', '--test'])
        logger.debug("rsw-postgresql-configure-settings is callable.")
        sys.exit(0)

    if not postgres_initialized():
        init_postgres()

    configure_postgres_auth(args.hba_file, debug=args.debug)
    configure_postgres_other_settings(args.postgresql_conf_file, debug=args.debug)
    configure_postgres_service()
    logger.info("PostgreSQL 9.4 configured.")

if __name__ == "__main__":
    main()
