from fastapi.exceptions import HTTPException
from sfm.models import Project, WorkItem
from sqlmodel import Session, select
from opencensus.ext.azure.log_exporter import AzureLogHandler
from sfm.config import get_settings
from sfm.logger import create_logger
from sfm.utils import (
    create_project_auth_token,
    hash_project_auth_token,
    verify_admin_key,
)

app_settings = get_settings()


logger = create_logger(__name__)


def get_all(db: Session, skip: int = None, limit: int = None):
    """Get all the projects and return them."""
    projects = db.exec(
        select(Project).order_by(Project.id).offset(skip).limit(limit)
    ).all()
    if not projects:
        logger.debug("Projects not found")
        raise HTTPException(status_code=404, detail="Projects not found")
    return projects


def get_by_id(db: Session, project_id: int):
    """Get the project with corresponding id and return it."""
    project = db.get(Project, project_id)
    if not project:
        logger.debug("Projects not found")
        raise HTTPException(status_code=404, detail="Project not found")
    return project


def create_project(db: Session, project_data, admin_key):
    """Take data from request and create a new project in the database."""
    project_name_repeat = db.exec(
        select(Project).where(Project.name == project_data.name)
    ).first()

    if project_name_repeat is not None:
        logger.debug("Database entry already exists")
        raise HTTPException(status_code=409, detail="Database entry already exists")

    verified_admin = verify_admin_key(admin_key)
    if verified_admin:
        project_temp = project_data.dict()
        token = create_project_auth_token()
        hashed_token = hash_project_auth_token(token)
        project_temp.update({"project_auth_token_hashed": hashed_token})
        project_db = Project(**project_temp)
        db.add(project_db)
        db.commit()
    else:
        logger.warning("Attempted to verify as an admin with incorrect credentials")
        raise HTTPException(status_code=401, detail="Credentials are incorrect")

    # Check the new record
    db.refresh(project_db)
    new_project = db.get(Project, project_db.id)
    if new_project.name == project_data.name:
        return [new_project, token]  # successfully created record
    else:
        logger.error("Project did not store correctly in database")
        return False  # didn't store correctly


def delete_project(db: Session, project_id, admin_key):
    """Take a project_name and remove the row from the database."""
    verified_admin = verify_admin_key(admin_key)
    if verified_admin:
        project = db.get(Project, project_id)
        if not project:
            logger.debug("Project not found")
            raise HTTPException(status_code=404, detail="Project not found")

        for item in project.work_items:
            db.delete(item)
        db.delete(project)
        db.commit()
    else:
        logger.warning("Attempted to verify as admin with incorrect credentials")
        raise HTTPException(status_code=401, detail="Credentials are incorrect")

    # Check our work
    row = db.get(Project, project_id)
    if row:
        logger.error("Project did not delete correctly")
        return False  # Row didn't successfully delete or another one exists
    else:
        return True  # Successful deletion


def refresh_project_key(db: Session, project_id, admin_key):
    verified_admin = verify_admin_key(admin_key)

    if verified_admin:
        project_db = db.get(Project, project_id)
        if not project_db:
            logger.debug("Project with matching id not found")
            raise HTTPException(
                status_code=404, detail="Project with matching id not found"
            )
        new_token = create_project_auth_token()
        hashed_token = hash_project_auth_token(new_token)
        project_db.project_auth_token_hashed = hashed_token
        db.add(project_db)
        db.commit()
    else:
        logger.warning("Attempted to verify as admin with incorrect credentials")
        raise HTTPException(status_code=401, detail="Credentials are incorrect")

    check = db.exec(
        select(Project).where(Project.project_auth_token_hashed == hashed_token)
    )
    if check:
        return new_token
    else:
        logger.error("Project auth token did not update correctly")
        return False


def update_project(db: Session, project_id, project_data, admin_key):
    """Take data from request and update an existing Project in the database."""

    verified_admin = verify_admin_key(admin_key)
    if verified_admin:
        project = db.get(Project, project_id)
        if not project:
            logger.debug("Project not found")
            raise HTTPException(status_code=404, detail="Project not found")

        project_newdata = project_data.dict(exclude_unset=True, exclude_defaults=True)
        for key, value in project_newdata.items():
            setattr(project, key, value)

        db.add(project)
        db.commit()

    else:
        logger.warning("Attempted to verify as admin with incorrect credentials")
        raise HTTPException(status_code=401, detail="Credentials are incorrect")

    # return updated item
    db.refresh(project)
    if project:
        return project  # updated record
    else:
        logger.error("Project did not store correctly")
        return False  # didn't store correctly

sfm.logger.create_logger sfm.utils.verify_admin_key sfm.utils.create_project_auth_token sfm.models.Project sqlmodel.select sfm.utils.hash_project_auth_token fastapi.exceptions.HTTPException sfm.config.get_settings
[((382, 396), 'sfm.config.get_settings', 'get_settings', ([], {}), '()\n', (394, 396), False, 'from sfm.config import get_settings\n'), ((408, 431), 'sfm.logger.create_logger', 'create_logger', (['__name__'], {}), '(__name__)\n', (421, 431), False, 'from sfm.logger import create_logger\n'), ((1568, 1595), 'sfm.utils.verify_admin_key', 'verify_admin_key', (['admin_key'], {}), '(admin_key)\n', (1584, 1595), False, 'from sfm.utils import create_project_auth_token, hash_project_auth_token, verify_admin_key\n'), ((2590, 2617), 'sfm.utils.verify_admin_key', 'verify_admin_key', (['admin_key'], {}), '(admin_key)\n', (2606, 2617), False, 'from sfm.utils import create_project_auth_token, hash_project_auth_token, verify_admin_key\n'), ((3466, 3493), 'sfm.utils.verify_admin_key', 'verify_admin_key', (['admin_key'], {}), '(admin_key)\n', (3482, 3493), False, 'from sfm.utils import create_project_auth_token, hash_project_auth_token, verify_admin_key\n'), ((4589, 4616), 'sfm.utils.verify_admin_key', 'verify_admin_key', (['admin_key'], {}), '(admin_key)\n', (4605, 4616), False, 'from sfm.utils import create_project_auth_token, hash_project_auth_token, verify_admin_key\n'), ((730, 789), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(404)', 'detail': '"""Projects not found"""'}), "(status_code=404, detail='Projects not found')\n", (743, 789), False, 'from fastapi.exceptions import HTTPException\n'), ((1039, 1097), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(404)', 'detail': '"""Project not found"""'}), "(status_code=404, detail='Project not found')\n", (1052, 1097), False, 'from fastapi.exceptions import HTTPException\n'), ((1475, 1545), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(409)', 'detail': '"""Database entry already exists"""'}), "(status_code=409, detail='Database entry already exists')\n", (1488, 1545), False, 'from fastapi.exceptions import HTTPException\n'), ((1678, 1705), 'sfm.utils.create_project_auth_token', 'create_project_auth_token', ([], {}), '()\n', (1703, 1705), False, 'from sfm.utils import create_project_auth_token, hash_project_auth_token, verify_admin_key\n'), ((1729, 1759), 'sfm.utils.hash_project_auth_token', 'hash_project_auth_token', (['token'], {}), '(token)\n', (1752, 1759), False, 'from sfm.utils import create_project_auth_token, hash_project_auth_token, verify_admin_key\n'), ((1854, 1877), 'sfm.models.Project', 'Project', ([], {}), '(**project_temp)\n', (1861, 1877), False, 'from sfm.models import Project, WorkItem\n'), ((2034, 2100), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(401)', 'detail': '"""Credentials are incorrect"""'}), "(status_code=401, detail='Credentials are incorrect')\n", (2047, 2100), False, 'from fastapi.exceptions import HTTPException\n'), ((3056, 3122), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(401)', 'detail': '"""Credentials are incorrect"""'}), "(status_code=401, detail='Credentials are incorrect')\n", (3069, 3122), False, 'from fastapi.exceptions import HTTPException\n'), ((3801, 3828), 'sfm.utils.create_project_auth_token', 'create_project_auth_token', ([], {}), '()\n', (3826, 3828), False, 'from sfm.utils import create_project_auth_token, hash_project_auth_token, verify_admin_key\n'), ((3852, 3886), 'sfm.utils.hash_project_auth_token', 'hash_project_auth_token', (['new_token'], {}), '(new_token)\n', (3875, 3886), False, 'from sfm.utils import create_project_auth_token, hash_project_auth_token, verify_admin_key\n'), ((4100, 4166), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(401)', 'detail': '"""Credentials are incorrect"""'}), "(status_code=401, detail='Credentials are incorrect')\n", (4113, 4166), False, 'from fastapi.exceptions import HTTPException\n'), ((5165, 5231), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(401)', 'detail': '"""Credentials are incorrect"""'}), "(status_code=401, detail='Credentials are incorrect')\n", (5178, 5231), False, 'from fastapi.exceptions import HTTPException\n'), ((2775, 2833), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(404)', 'detail': '"""Project not found"""'}), "(status_code=404, detail='Project not found')\n", (2788, 2833), False, 'from fastapi.exceptions import HTTPException\n'), ((3675, 3750), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(404)', 'detail': '"""Project with matching id not found"""'}), "(status_code=404, detail='Project with matching id not found')\n", (3688, 3750), False, 'from fastapi.exceptions import HTTPException\n'), ((4774, 4832), 'fastapi.exceptions.HTTPException', 'HTTPException', ([], {'status_code': '(404)', 'detail': '"""Project not found"""'}), "(status_code=404, detail='Project not found')\n", (4787, 4832), False, 'from fastapi.exceptions import HTTPException\n'), ((4197, 4212), 'sqlmodel.select', 'select', (['Project'], {}), '(Project)\n', (4203, 4212), False, 'from sqlmodel import Session, select\n'), ((1295, 1310), 'sqlmodel.select', 'select', (['Project'], {}), '(Project)\n', (1301, 1310), False, 'from sqlmodel import Session, select\n'), ((577, 592), 'sqlmodel.select', 'select', (['Project'], {}), '(Project)\n', (583, 592), False, 'from sqlmodel import Session, select\n')]