# -*- coding: UTF-8 -*-
#
# Copyright (C) 2014 Avencall
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>

import argparse
import logging
import xivo_dao.alchemy.all  # imports all the sqlalchemy model

from xivo_dao.helpers import db_manager
from xivo_dao.helpers.db_manager import Base
from xivo_db import alembic
from xivo_db import postgres

logger = logging.getLogger(__name__)


def _create_tables():
    logger.info('Creating all tables...')
    Base.metadata.create_all()


def _populate_db():
    logger.info('Populating database...')
    postgres.populate_db()


def _create_user_stats():
    db_user = 'stats'
    db_user_password = 'stats'

    conn = postgres.create_db_connection(db_name='asterisk')
    postgres.create_user(conn, db_user, db_user_password)

    # Grant usage on schema xc
    sql_grantusage_schema = 'GRANT USAGE ON SCHEMA xc TO stats'
    # Grant rights on already created tables, sequences
    sql_select_right_on_tables = 'GRANT SELECT ON ALL TABLES IN SCHEMA public, xc TO stats'
    sql_select_right_on_sequences = 'GRANT SELECT ON ALL SEQUENCES IN SCHEMA public, xc TO stats'
    # Grant default rights for tables, sequences created afterward
    sql_default_privilege_on_tables = 'ALTER DEFAULT PRIVILEGES FOR ROLE asterisk IN SCHEMA public, xc GRANT SELECT ON TABLES TO stats'
    sql_default_privilege_on_sequences = 'ALTER DEFAULT PRIVILEGES FOR ROLE asterisk IN SCHEMA public, xc GRANT SELECT ON SEQUENCES TO stats'
    with conn:
        with conn.cursor() as cursor:
            cursor.execute(sql_grantusage_schema)
            cursor.execute(sql_select_right_on_tables)
            cursor.execute(sql_select_right_on_sequences)
            cursor.execute(sql_default_privilege_on_tables)
            cursor.execute(sql_default_privilege_on_sequences)

def _create_user_db_replic():
    db_user = 'dbreplic'
    db_user_password = 'dbreplic'

    conn = postgres.create_db_connection(db_name='asterisk')
    postgres.create_user(conn, db_user, db_user_password)

    # Grant usage on schema xc
    sql_grantusage_schema = 'GRANT USAGE ON SCHEMA xc TO dbreplic'
    # Grant rights on already created tables, sequences
    sql_select_right_on_tables = 'GRANT SELECT ON ALL TABLES IN SCHEMA public, xc TO dbreplic'
    sql_select_right_on_sequences = 'GRANT SELECT ON ALL SEQUENCES IN SCHEMA public, xc TO dbreplic'
    # Grant default rights for tables, sequences created afterward
    sql_default_privilege_on_tables = 'ALTER DEFAULT PRIVILEGES FOR ROLE asterisk IN SCHEMA public, xc GRANT SELECT ON TABLES TO dbreplic'
    sql_default_privilege_on_sequences = 'ALTER DEFAULT PRIVILEGES FOR ROLE asterisk IN SCHEMA public, xc GRANT SELECT ON SEQUENCES TO dbreplic'
    sql_write_right_on_replication_state = 'GRANT SELECT, INSERT, UPDATE ON replication_state TO dbreplic'

    with conn:
        with conn.cursor() as cursor:
            cursor.execute(sql_grantusage_schema)
            cursor.execute(sql_select_right_on_tables)
            cursor.execute(sql_select_right_on_sequences)
            cursor.execute(sql_default_privilege_on_tables)
            cursor.execute(sql_default_privilege_on_sequences)
            cursor.execute(sql_write_right_on_replication_state)

def _drop_db():
    logger.info('Dropping database...')
    postgres.drop_db()


def _init_db():
    logger.info('Initializing database...')
    postgres.init_db()
    alembic.stamp_head()
    db_manager.init_db_from_config()


def main():
    parsed_args = _parse_args()

    _init_logging(parsed_args.verbose)

    if parsed_args.drop:
        _drop_db()

    if parsed_args.init:
        _init_db()
        _create_tables()
        _populate_db()
        _create_user_stats()
        _create_user_db_replic()


def _parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('-v', '--verbose', action='store_true',
                        help='increase verbosity')
    parser.add_argument('--drop', action='store_true',
                        help='drop database')
    parser.add_argument('--init', action='store_true',
                        help='initialize database')
    return parser.parse_args()


def _init_logging(verbose):
    logger = logging.getLogger()
    handler = logging.StreamHandler()
    handler.setFormatter(logging.Formatter('%(message)s'))
    logger.addHandler(handler)
    if verbose:
        logger.setLevel(logging.INFO)
    else:
        logger.setLevel(logging.ERROR)
