use crate::commands::{Cli, Result};
use clap::{Parser, Subcommand};

mod list_clients;
mod list_invoice;
mod list_invoices;
mod list_jobs;
mod list_tags;
mod list_work;
mod list_workers;

use list_clients::ListClients;
use list_invoice::ListInvoice;
use list_invoices::ListInvoices;
use list_jobs::ListJobs;
use list_tags::ListTags;
use list_work::ListWork;
use list_workers::ListWorkers;

/// List database entities
///
/// List jobs, clients, workers or a job's work from database.
#[derive(Parser)]
pub(crate) struct List {
    #[command(subcommand)]
    pub(crate) command: ListCommand,
}

#[derive(Subcommand)]
pub(crate) enum ListCommand {
    /// List workers
    Workers(ListWorkers),
    /// List clients
    Clients(ListClients),
    /// List jobs
    Jobs(ListJobs),
    /// List job's done work
    #[command(visible_alias = "job")]
    Work(ListWork),
    /// List known tags
    Tags(ListTags),
    /// List invoices
    Invoices(ListInvoices),
    /// List work of an invoice
    Invoice(ListInvoice),
}

impl List {
    pub(crate) fn run(&self, cli: &Cli) -> Result<()> {
        match &self.command {
            ListCommand::Workers(list) => list.run(cli),
            ListCommand::Clients(list) => list.run(cli),
            ListCommand::Jobs(list) => list.run(cli),
            ListCommand::Work(list) => list.run(cli),
            ListCommand::Tags(list) => list.run(cli),
            ListCommand::Invoices(list) => list.run(cli),
            ListCommand::Invoice(list) => list.run(cli),
        }
    }
}
