import click

from wurker.settings import conf
from wurker.db import get_drone_status
from wurker.cli.base import BaseCommand
from wurker.drone import make_drone_clients
from wurker.models import WurkerBee, WurkerCron, WurkerCommand, WurkerQueue


class RemoveCommand(BaseCommand):
    """Encapsulate remove command."""

    def __init__(self, logger=None):
        BaseCommand.__init__(self, logger=logger, check_schema=True)

        # We might need drone API auth
        self.drone_api_auth = conf.ApiAuth


    def run(self, option:str, key:str, drones:list=[]):
        """Remove a Wurker definition."""

        # Run via Drone API?
        if drones:
            return self.run_drone(option, key, drones)

        if option == "command":
            return self.rm_command(key)
        elif option == "cron":
            return self.rm_cron(key)
        elif option == "bee":
            return self.rm_bee(key)
        elif option == "ondemand":
            return self.rm_ondemand(key)
        else:
            raise ValueError(f"Invalid 'option' value: '{option}'")


    def rm_command(self, key:str):
        """Remove a Wurker Command definition."""

        with self.RemoteSession() as db:
            command = db.query(WurkerCommand).filter(
                WurkerCommand.app_id == self.app_id,
                WurkerCommand.slug == key,
            ).first()

            if command is None:
                raise ValueError(f"Wurker Command not found: '{key}'")

            db.delete(command)
            db.commit()


    def rm_cron(self, key:str):
        """Remove a Wurker Cron definition."""

        with self.RemoteSession() as db:
            cron = db.query(WurkerCron).filter(
                WurkerCron.app_id == self.app_id,
                WurkerCron.slug == key,
            ).first()

            if cron is None:
                raise ValueError(f"Wurker Cron not found: '{key}'")

            db.delete(cron)
            db.commit()


    def rm_bee(self, key:str):
        """Remove a Wurker Bee definition."""

        with self.RemoteSession() as db:
            bee = db.query(WurkerBee).filter(
                WurkerBee.app_id == self.app_id,
                WurkerBee.slug == key,
            ).first()

            if bee is None:
                raise ValueError(f"Wurker Bee not found: '{key}'")

            db.delete(bee)
            db.commit()


    def rm_ondemand(self, key:str):
        """Remove a Wurker on-demand Bee definition."""

        with self.RemoteSession() as db:
            # 1st get the Bee itself
            bee = db.query(WurkerBee).filter(
                WurkerBee.app_id == self.app_id,
                WurkerBee.slug == key,
            ).first()

            if bee is None:
                raise ValueError(f"Wurker Bee not found: '{key}'")

            queued = db.query(WurkerQueue).filter(
                WurkerQueue.app_id == self.app_id,
                WurkerQueue.wurker_bee_id == bee.id,
            ).all()

            if not len(queued):
                raise ValueError(f"Wurker Bee not queued: '{key}'")

            for item in queued:
                db.delete(item)

            db.commit()


    def run_drone(self, option:str, key:str, drones:list):
        """Run via Drone API(s)."""

        drone_status = get_drone_status(self.remote_db_conf, self.app_id, drones=drones)
        if drone_status is None or not len(drone_status):
            click.echo(f"WARNING: Queen ({self.app_id}) Drones have no 'wurker_status' data", err=True)
            return

        drone_clients = make_drone_clients(drone_status, auth=self.drone_api_auth)

        for app_id, drone in drone_clients.items():
            drone.post_remove(option, key)
