#!/usr/bin/env python
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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 os
import ConfigParser

from alembic import command
from alembic.config import Config as AlembicConfig


def main():
    config_folder = _create_config_folder()
    _create_config_file(config_folder)
    _create_database()


def _create_config_folder():
    config_folder = os.path.join(os.path.expanduser('~'), '.gstack')
    if not os.path.exists(config_folder):
        os.makedirs(config_folder)
    os.chmod(config_folder, 0o700)
    return config_folder


def _create_config_file(config_folder):
    config_file_path = config_folder + '/gstack.conf'
    config = _modify_config_profile(config_file_path)
    config_file = open(config_file_path, 'w+')
    config.write(config_file)


def _modify_config_profile(config_file, profile='initial'):
    config = ConfigParser.SafeConfigParser()
    config.read(config_file)

    if not config.has_section(profile):
        config.add_section(profile)

    config = _set_attribute_of_profile(
        config, profile, 'gstack_bind_address', 'gstack bind address', 'localhost'
    )
    config = _set_attribute_of_profile(
        config, profile, 'gstack_port', 'gstack bind port', '5000'
    )
    config = _set_attribute_of_profile(
        config, profile, 'cloudstack_host', 'Cloudstack host', 'localhost'
    )
    config = _set_attribute_of_profile(
        config, profile, 'cloudstack_port', 'Cloudstack port', '8080'
    )
    config = _set_attribute_of_profile(
        config, profile, 'cloudstack_protocol', 'Cloudstack protocol', 'http'
    )
    config = _set_attribute_of_profile(
        config, profile, 'cloudstack_path', 'Cloudstack path', '/client/api'
    )

    return config


def _set_attribute_of_profile(config, profile, attribute, message, default):
    if config.has_option(profile, attribute):
        default = config.get(profile, attribute)

    attribute_value = _read_in_config_attribute_or_use_default(message, default)

    config.set(profile, attribute, attribute_value)
    return config


def _read_in_config_attribute_or_use_default(message, default):
    attribute = raw_input(message + ' [' + default + ']: ')
    if attribute == '':
        attribute = default

    return attribute


def _create_database():
    directory = os.path.join(os.path.dirname(__file__), '../migrations')
    database_config = AlembicConfig(os.path.join(
        directory,
        'alembic.ini'
    ))
    database_config.set_main_option('script_location', directory)
    command.upgrade(database_config, 'head', sql=False, tag=None)
