#!python
# -*- coding: utf-8 -*-
# gthnk (c) Ian Dennis Miller

import sys
import os
import glob

from flask_script import Manager, Shell, Server
from flask_migrate import Migrate, MigrateCommand
import alembic
import alembic.config

from sqlalchemy.exc import OperationalError

sys.path.insert(0, './src')

from gthnk import db
from gthnk.__meta__ import __version__
from gthnk.server import create_app
from gthnk.models.user import User
from gthnk.models.day import Day
from gthnk.models.entry import Entry
from gthnk.models.page import Page
from gthnk.adaptors.journal_buffer import TextFileJournalBuffer
from gthnk.librarian import Librarian
from gthnk.integrations import make_config, write_config_file


app = create_app()
migrate = Migrate(app, db, directory="src/gthnk/migrations")


def _make_context():
    return {
        "app": app,
        "db": db,
    }

manager = Manager(app)
manager.add_command("shell", Shell(make_context=_make_context))
manager.add_command('db', MigrateCommand)


@manager.option('-u', '--username', help='username', required=True)
@manager.option('-p', '--password', help='password', required=True)
def user_add(username, password):
    "add a user to the database"
    User.create_with_password(
        username=username,
        password=password
    )


@manager.option('-u', '--username', help='username', required=True)
def user_del(username):
    "delete a user from the database"
    obj = User.find(username=username)
    if obj:
        obj.delete()
        print("Deleted")
    else:
        print("User not found")


@manager.option('-u', '--username', help='username', required=True)
@manager.option('-p', '--password', help='password', required=True)
def change_password(username, password):
    "change a user password"
    u = User.find(username=username)
    if u:
        u.change_password(password)


@manager.command
def drop_db():
    """
    drop all databases
    """
    db.reflect()
    db.drop_all()


@manager.command
def init_db():
    "drop all databases, instantiate schemas"
    db.drop_all()

    # create database from model schema directly
    db.create_all()
    db.session.commit()

    # "stamp" database with version for alembic
    cfg = alembic.config.Config("src/gthnk/migrations/alembic.ini")
    alembic.command.stamp(cfg, "head")


@manager.option('-d', '--directory', help='directory', required=True)
def import_archive(directory):
    """
    Import archive of journal files
    """
    with app.app_context():
        journal_buffer = TextFileJournalBuffer()
        match_str = os.path.join(directory, "*.txt")
        journal_buffer.process_list(glob.glob(match_str))
        journal_buffer.save_entries()


@manager.command
def journal_export():
    """
    Export journal files
    """
    with app.app_context():
        librarian = Librarian(app)
        librarian.export_journal()


@manager.command
def journal_rotate():
    """
    Rotate journal files
    """
    with app.app_context():
        librarian = Librarian(app)
        librarian.rotate_buffers()


@manager.command
def do_install():
    """
    integrate Gthnk with the operating system
    """
    config = make_config()
    config["do_install"](config)


@manager.command
def do_uninstall():
    """
    remove Gthnk installation
    """
    config = make_config()
    config["do_uninstall"](config)


@manager.option('-f', '--filename', help='destination configuration filename', required=True)
@manager.option('-g', '--gthnk_path', help='path to gthnk data storage', required=True)
def init_config_file(filename, gthnk_path):
    "initialize a configuration file"
    write_config_file(out_file=filename, gthnk_path=gthnk_path)


@manager.command
def gui():
    """
    drop all databases
    """
    import webview
    webview.create_window('gthnk', 'http://localhost:1620')
    webview.start()

if __name__ == "__main__":
    manager.run()
