#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (2018) Hewlett Packard Enterprise Development LP
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.


import sys

# Checking Python version
if not sys.version_info >= (3,5):
    sys.exit("oneview-redfish-toolkit requires Python '>=3.5'")


import argparse
import os
import appdirs
import pkg_resources
import configparser
import shutil
import oneview_redfish_toolkit.app

ENCODING = 'utf-8'
CFG_DIR_NAME = 'oneview-redfish-toolkit'
REDFISH_CFG_FILE_NAME = 'redfish.conf'
LOGGING_CFG_FILE_NAME = 'logging.conf'

CERTS_DIR_NAME = 'certs'
CERTS_CRT_FILE_NAME = 'self-signed.crt'
CERTS_KEY_FILE_NAME = 'self-signed.key'

DEFAULT_LOG_PATH = 'redfish.log'
PERF_LOG_PATH = 'redfish_performance.log'
OV_LOG_PATH = 'redfish_ov_data.log'


def get_config_file_path(file_name):
    """Read redfish configuration file and return its contents
    """
    cfg_dir = appdirs.user_config_dir(CFG_DIR_NAME)
    cgf_file_path = os.path.join(cfg_dir, file_name)

    if not os.path.isfile(cgf_file_path):
        create_config_file(cfg_dir, file_name)

    return cgf_file_path


def get_config_file(file_name):
    """Read configuration file and return its contents
    """
    cgf_file_path = get_config_file_path(file_name)
    config = configparser.ConfigParser()
    config.optionxform = str
    config.read(cgf_file_path)
    return config


def create_config_file(file_dir, file_name):
    """Create config file
    """
    source = pkg_resources.resource_filename(
        oneview_redfish_toolkit.__name__, os.path.join('conf', file_name))
    os.makedirs(name=file_dir, exist_ok=True)
    shutil.copyfile(source, os.path.join(file_dir, file_name))


def get_config_dir_path(dir_name):
    """Returns path from the directory name passed as arguments
    on the user config directory. If the directory not exists
    will be created copying files from application lib dir.
    """
    cfg_dir = appdirs.user_config_dir(CFG_DIR_NAME)
    cgf_dir_path = os.path.join(cfg_dir, dir_name)

    if not os.path.isdir(cgf_dir_path):
        os.makedirs(name=cgf_dir_path, exist_ok=True)

    return cgf_dir_path


def get_path_redfish_conf():
    """Get path for redfish.conf """
    config_path = get_config_file_path(REDFISH_CFG_FILE_NAME)
    config = get_config_file(REDFISH_CFG_FILE_NAME)

    ov_ip = config['oneview_config']['ip']
    certs_dir = config['ssl']['SSLCertFile']

    save_file = not (ov_ip and certs_dir)

    if not ov_ip:
        ov_ip = str(input('Set Oneview IP: '))
        config['oneview_config']['ip'] = ov_ip

    if not certs_dir:
        certs_dir = get_config_dir_path(CERTS_DIR_NAME)
        config['ssl']['SSLCertFile'] = os.path.join(
            certs_dir, CERTS_CRT_FILE_NAME)
        config['ssl']['SSLKeyFile'] = os.path.join(
            certs_dir, CERTS_KEY_FILE_NAME)

    if save_file:
        with open(config_path, 'w') as configfile:
            config.write(configfile)
            print('Configuration file saved: ' + config_path)

    return config_path


def get_handler_file_path(logging, handler_name):
    arg_property = logging[handler_name]['args']

    if len(arg_property.split("'")) > 1:
        return arg_property.split("'")[1]

    return ''


def get_path_logging_conf():
    logging_path = get_config_file_path(LOGGING_CFG_FILE_NAME)
    logging = get_config_file(logging_path)

    app_default_log_path = \
        get_handler_file_path(logging, 'handler_defaultFileHandler')
    app_perf_log_path = \
        get_handler_file_path(logging, 'handler_performanceFileHandler')
    app_ov_log_path = \
        get_handler_file_path(logging, 'handler_oneviewDataFileHandler')

    if app_default_log_path == DEFAULT_LOG_PATH and \
        app_perf_log_path == PERF_LOG_PATH and \
        app_ov_log_path == OV_LOG_PATH:

        cfg_dir = appdirs.user_config_dir(CFG_DIR_NAME)

        logging['handler_defaultFileHandler']['args'] = \
            logging['handler_defaultFileHandler']['args'].\
            replace(app_default_log_path, os.path.join(cfg_dir,
                                                       app_default_log_path))

        logging['handler_performanceFileHandler']['args'] = \
            logging['handler_performanceFileHandler']['args'].\
            replace(app_perf_log_path, os.path.join(cfg_dir,
                                                    app_perf_log_path))

        logging['handler_oneviewDataFileHandler']['args'] = \
            logging['handler_oneviewDataFileHandler']['args'].\
            replace(app_ov_log_path, os.path.join(cfg_dir,
                                                  app_ov_log_path))

        with open(logging_path, 'w') as configfile:
            logging.write(configfile)

        print('Logging file saved: ' + logging_path)

    return logging_path


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='This toolkit provides a REST service to answer \
        DMTF\'s Redfish compliant requests by querying HPE OneView.')
    parser.add_argument('--config', type=str,
                        help='A path to config file')
    parser.add_argument('--log-config', type=str,
                        help='A path to logging config file')
    args = parser.parse_args()

    config_logging_path = args.log_config or get_path_logging_conf()

    config_path = args.config or get_path_redfish_conf()
    print('Using configuration file: ' + config_path)

    oneview_redfish_toolkit.app.main(config_path, config_logging_path)
