#!/usr/bin/env python
# encoding: utf-8
#
#  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.
#

"""This module creates the flask application.
"""

import os
import sys
import argparse

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

from flask import Flask
from ConfigParser import SafeConfigParser

from ec2stack.controllers import *
from ec2stack.core import DB
from ec2stack.models import User


def create_app(settings=None):
    """
    Creates a flask application.

    @param settings: Settings override object.
    @return: The flask application.
    """
    app = Flask(__name__)

    if settings:
        app.config.from_object(settings)
    else:
        args = _generate_args()
        profile = args.pop('profile')
        app.config['DEBUG'] = args.pop('debug')
        config_file = _load_config_file()
        database_uri = _load_database()
        _config_from_config_profile(config_file, profile, app)
        app.config['SQLALCHEMY_DATABASE_URI'] = database_uri

    DB.init_app(app)

    default_controller = __import__(
        'ec2stack.controllers.' + 'default', None, None, 'DEFAULT'
    )
    default_controller = getattr(default_controller, 'DEFAULT')
    app.register_blueprint(default_controller)

    return app


def _generate_args():
    """
    Generate command line arguments for ec2stack-configure.

    @return: args.
    """
    parser = argparse.ArgumentParser()

    parser.add_argument(
        '-p',
        '--profile',
        required=False,
        help='The profile to run ec2stack with, default is initial',
        default='initial'
    )

    parser.add_argument(
        '-d',
        '--debug',
        required=False,
        help='Turn debug on for application',
        default=False
    )

    args = parser.parse_args()

    return vars(args)


def _load_config_file():
    """
    Checks that the user's configuration file exists and returns its path.

    @return: The path to the user's configuration file.
    """
    config_file = os.path.join(
        os.path.expanduser('~'),
        '.ec2stack/ec2stack.conf'
    )

    if not os.path.exists(config_file):
        sys.exit('No configuration found, please run ec2stack-configure')

    return config_file


def _config_from_config_profile(config_file, profile, app):
    """
    Configures ec2stack app based on configuration profile.

    @param config_file: current config file configuration.
    @param profile: the profile to set the attribute in.
    """
    config = SafeConfigParser()
    config.read(config_file)

    if not config.has_section(profile):
        sys.exit('No profile matching ' + profile +
                 ' found in configuration, please run ec2stack-configure -p ' + profile)

    for attribute in config.options(profile):
        app.config[attribute.upper()] = config.get(profile, attribute)

    instance_type_map = {}
    instance_section = profile + "instancemap"
    if config.has_section(instance_section):
        for attribute in config.options(instance_section):
            instance_type_map[attribute] = config.get(
                instance_section, attribute)

    app.config['INSTANCE_TYPE_MAP'] = instance_type_map

    resource_type_map = {}
    resource_section = profile + "resourcemap"
    if config.has_section(resource_section):
        for attribute in config.options(resource_section):
            resource_type_map[attribute] = config.get(
                resource_section, attribute)

    app.config['RESOURCE_TYPE_MAP '] = resource_type_map


def _load_database():
    """
    Checks that the user's database exists and returns its uri.

    @return: The uri to the user's database.
    """
    database_file = os.path.join(
        os.path.expanduser('~'),
        '.ec2stack/ec2stack.sqlite'
    )

    if not os.path.exists(database_file):
        directory = os.path.join(os.path.dirname(__file__), '../migrations')
        config = AlembicConfig(os.path.join(
            directory,
            'alembic.ini'
        ))
        config.set_main_option('script_location', directory)
        command.upgrade(config, 'head', sql=False, tag=None)

    return 'sqlite:///' + database_file
