"""All of the configuration for the service is captured here. All items are loaded, or have Constants defined here that are loaded into the Flask configuration. All modules and lookups get their configuration from the Flask config, rather than reading environment variables directly or by accessing this configuration directly.
"""

import os
import sys

from dotenv import find_dotenv, load_dotenv

# this will load all the envars from a .env file located in the project root (api)
load_dotenv(find_dotenv())

CONFIGURATION = {
    'development': 'config.DevConfig',
    'testing': 'config.TestConfig',
    'production': 'config.ProdConfig',
    'default': 'config.ProdConfig'
}


def get_named_config(config_name: str = 'production'):
    """Return the configuration object based on the name

    :raise: KeyError: if an unknown configuration is requested
    """
    if config_name in ['production', 'staging', 'default']:
        config = ProdConfig()
    elif config_name == 'testing':
        config = TestConfig()
    elif config_name == 'development':
        config = DevConfig()
    else:
        raise KeyError(f"Unknown configuration '{config_name}'")
    return config


class _Config(object):  # pylint: disable=too-few-public-methods
    """Base class configuration that should set reasonable defaults for all the other configurations."""
    
    PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))

    SECRET_KEY = 'a secret'
    # which DBMS system should use, defaulted to postgres database.
    DBMS = os.getenv('DBMS', 'POSTGRES')

    # POSTGRESQL
    DB_PG_CONFIG = {
        'host': os.getenv('DATABASE_HOST', ''),
        'port': os.getenv('DATABASE_PORT', '5432'),
        'dbname': os.getenv('DATABASE_NAME', ''),
        'user': os.getenv('DATABASE_USERNAME', ''),
        'password': os.getenv('DATABASE_PASSWORD', '')
    }

    # SQL SERVER
    DB_MSSQL_CONFIG = {
        'server':os.getenv('DATABASE_HOST', ''),
        'port': os.getenv('DATABASE_PORT', '1433'),
        'database': os.getenv('DATABASE_NAME', ''),
        'user': os.getenv('DATABASE_USERNAME', ''),
        'password': os.getenv('DATABASE_PASSWORD', '')
    }

    DATABASE_TABLE_NAME = os.getenv('DATABASE_TABLE_NAME')
    DATABASE_INPUT_COLUMN = os.getenv('DATABASE_INPUT_COLUMN')
    DATABASE_OUTPUT_COLUMN = os.getenv('DATABASE_OUTPUT_COLUMN')
    MODEL_ID = os.getenv('MODEL_ID')
    SCHEMA_NAME = os.getenv('SCHEMA_NAME',None)
    TESTING = False
    DEBUG = True


class DevConfig(_Config):  # pylint: disable=too-few-public-methods
    TESTING = False
    DEBUG = True


class TestConfig(_Config):  # pylint: disable=too-few-public-methods
    """In support of testing only used by the py.test suite."""
    DEBUG = True
    TESTING = True


class ProdConfig(_Config):  # pylint: disable=too-few-public-methods
    """Production environment configuration."""

    SECRET_KEY = os.getenv('SECRET_KEY', None)

    if not SECRET_KEY:
        SECRET_KEY = os.urandom(24)
        print('WARNING: SECRET_KEY being set as a one-shot', file=sys.stderr)

    TESTING = False
    DEBUG = False
