import sys
import os
import click
from app import config
from sqlmodel import Session
from sqlmodel import create_engine
from app.models.server import Server
from sqlmodel import select

API_ENVIRONMENT = os.environ.get("API_ENVIRONMENT", "Testing")
settings = getattr(sys.modules[__name__].config, API_ENVIRONMENT)

engine = create_engine(settings.DATABASE_URI)


@click.group()
@click.pass_context
def main():
    pass


@main.command(name="settings")
def get_settings():
    """
    Prints current API settings from $API_ENVIRONMENT.
    """
    click.echo(settings)


@main.group(name="import")
def import_group():
    pass

@import_group.command(name="catagories")
def import_catagories():
    """
    Commands for importing a database.
    """

    import yaml
    from app.models.server import Catagory, ServerCatagoryLink
    print("Looking for catagories.yml")

    with Session(engine) as session:
        with open("config.yml", "r") as stream:
            catagories = yaml.safe_load(stream)

            for name, data in catagories.get("catagories").items():
                print(data)
                _catagory = Catagory(
                    title = name,
                    meta_ref = name.lower().replace(" ", "-"),
                    color = f"#{data['color']}"
                )

                session.add(_catagory)
                session.commit()
                session.refresh(_catagory)

                _query = select(Server).where(Server.domain_name.like(data['match']))
                _result = session.exec(_query).all()
                for server in _result:
                    _link = ServerCatagoryLink(
                        server_id = server.id,
                        catagory_id = _catagory.id
                    )
                    session.add(_link)
                session.commit()

@import_group.command(name="csv")
def csv_file(file):
    """
    Commands for importing a database.
    """
    import csv

    with Session(engine) as session:
        with open(file, "r") as stream:
            csv_reader = csv.DictReader(stream)
            line_count = 0
            for row in csv_reader:
                if line_count == 0:
                    line_count += 1

                _server = Server(
                    domain_name=row["Domain Name"],
                    domain_type=row["Domain Type"],
                    agency=row["Agency"],
                    organization=row["Organization"],
                )
                session.add(_server)
        session.commit()


@import_group.command(name="file")
@click.argument("file")
def basic_file(file):
    with Session(engine) as session:
        with open(file, "r") as stream:
            stream = stream.readlines()
            servers = []
            for row in stream:
                servers.append(row.strip().lower())

            for row in list(set(servers)):
                session.add(Server(domain_name=row))

        session.commit()


@main.group()
def tables():
    """
    Commands for handling database tables.
    """
    pass


@tables.command()
def drop():
    """
    Forcefully remove all tables within the database.
    """
    import sqlalchemy
    from sqlalchemy import create_engine
    from sqlalchemy import MetaData
    from sqlalchemy import inspect
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy.ext.declarative import declarative_base

    engine = create_engine(settings.DATABASE_URI)
    meta = MetaData()
    meta.reflect(bind=engine)
    meta.drop_all(engine, checkfirst=False)
    print("Dropped tables.")


@tables.command()
def create():
    """
    Creates all tables within the API.
    """
    from sqlmodel import SQLModel
    from app.models.user import User, Log
    from app.models.server import Server, ServerLog

    SQLModel.metadata.create_all(engine)
    print("Created tables.")


cli = click.CommandCollection(sources=[main])

if __name__ == "__main__":
    cli()

click.argument csv.DictReader app.models.server.ServerCatagoryLink click.group sqlalchemy.create_engine os.environ.get app.models.server.Server click.echo sqlalchemy.MetaData yaml.safe_load app.models.server.Server.domain_name.like click.CommandCollection sqlmodel.select sqlmodel.Session sqlmodel.SQLModel.metadata.create_all
[((205, 249), 'os.environ.get', 'os.environ.get', (['"""API_ENVIRONMENT"""', '"""Testing"""'], {}), "('API_ENVIRONMENT', 'Testing')\n", (219, 249), False, 'import os\n'), ((326, 362), 'sqlalchemy.create_engine', 'create_engine', (['settings.DATABASE_URI'], {}), '(settings.DATABASE_URI)\n', (339, 362), False, 'from sqlalchemy import create_engine\n'), ((366, 379), 'click.group', 'click.group', ([], {}), '()\n', (377, 379), False, 'import click\n'), ((2575, 2597), 'click.argument', 'click.argument', (['"""file"""'], {}), "('file')\n", (2589, 2597), False, 'import click\n'), ((3878, 3917), 'click.CommandCollection', 'click.CommandCollection', ([], {'sources': '[main]'}), '(sources=[main])\n', (3901, 3917), False, 'import click\n'), ((549, 569), 'click.echo', 'click.echo', (['settings'], {}), '(settings)\n', (559, 569), False, 'import click\n'), ((3420, 3456), 'sqlalchemy.create_engine', 'create_engine', (['settings.DATABASE_URI'], {}), '(settings.DATABASE_URI)\n', (3433, 3456), False, 'from sqlalchemy import create_engine\n'), ((3468, 3478), 'sqlalchemy.MetaData', 'MetaData', ([], {}), '()\n', (3476, 3478), False, 'from sqlalchemy import MetaData\n'), ((3804, 3840), 'sqlmodel.SQLModel.metadata.create_all', 'SQLModel.metadata.create_all', (['engine'], {}), '(engine)\n', (3832, 3840), False, 'from sqlmodel import SQLModel\n'), ((880, 895), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (887, 895), False, 'from sqlmodel import Session\n'), ((1972, 1987), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (1979, 1987), False, 'from sqlmodel import Session\n'), ((2629, 2644), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (2636, 2644), False, 'from sqlmodel import Session\n'), ((981, 1003), 'yaml.safe_load', 'yaml.safe_load', (['stream'], {}), '(stream)\n', (995, 1003), False, 'import yaml\n'), ((2065, 2087), 'csv.DictReader', 'csv.DictReader', (['stream'], {}), '(stream)\n', (2079, 2087), False, 'import csv\n'), ((2249, 2379), 'app.models.server.Server', 'Server', ([], {'domain_name': "row['Domain Name']", 'domain_type': "row['Domain Type']", 'agency': "row['Agency']", 'organization': "row['Organization']"}), "(domain_name=row['Domain Name'], domain_type=row['Domain Type'],\n    agency=row['Agency'], organization=row['Organization'])\n", (2255, 2379), False, 'from app.models.server import Server, ServerLog\n'), ((1465, 1503), 'app.models.server.Server.domain_name.like', 'Server.domain_name.like', (["data['match']"], {}), "(data['match'])\n", (1488, 1503), False, 'from app.models.server import Server, ServerLog\n'), ((1625, 1690), 'app.models.server.ServerCatagoryLink', 'ServerCatagoryLink', ([], {'server_id': 'server.id', 'catagory_id': '_catagory.id'}), '(server_id=server.id, catagory_id=_catagory.id)\n', (1643, 1690), False, 'from app.models.server import Catagory, ServerCatagoryLink\n'), ((2917, 2940), 'app.models.server.Server', 'Server', ([], {'domain_name': 'row'}), '(domain_name=row)\n', (2923, 2940), False, 'from app.models.server import Server, ServerLog\n'), ((1444, 1458), 'sqlmodel.select', 'select', (['Server'], {}), '(Server)\n', (1450, 1458), False, 'from sqlmodel import select\n')]