Skip to content
mod cache;
mod cli;
mod config;
mod github;
mod prompt;

use anyhow::{bail, Result};
use clap::Parser;

fn get_token() -> Result<String> {
    std::env::var("GITHUB_TOKEN")
        .map_err(|_| anyhow::anyhow!("GITHUB_TOKEN environment variable not set. Set it and try again, or run `pike setup`."))
}

async fn run_create_issue() -> Result<()> {
    let token = get_token()?;
    let config = config::Config::load()?;
    let mut cache = cache::Cache::load()?;

    if cache.repos.is_empty() {
        bail!("No cached repositories. Run `pike setup` first.");
    }

    let input = prompt::collect_issue_input(&config, &cache)?;
    let client = github::GitHubClient::new(&token);

    println!("Creating issue...");
    let issue = client
        .create_issue(&input.repo_full_name, &input.title, &input.description)
        .await?;
    println!("  Issue #{}: {}", issue.number, issue.html_url);

    if let Some(ref project) = input.project {
        println!("Adding to project \"{}\"...", project.title);
        let item_id = client
            .add_issue_to_project(&project.id, &issue.node_id)
            .await?;

        if let Some(ref status) = input.status {
            println!("Setting status to \"{}\"...", status.name);
            client
                .set_issue_status(
                    &project.id,
                    &item_id,
                    &project.status_field_id,
                    &status.id,
                )
                .await?;
            println!("  Status set to \"{}\"", status.name);
        }

        println!("  Added to project \"{}\"", project.title);
    }

    let project_id = input.project.as_ref().map(|p| p.id.as_str());
    cache.record_issue(&input.repo_full_name, project_id)?;

    Ok(())
}

async fn run_setup() -> Result<()> {
    let token = get_token()?;
    prompt::run_setup(&token).await
}

#[tokio::main]
async fn main() -> Result<()> {
    let cli = cli::Cli::parse();

    match cli.command {
        Some(cli::Commands::Setup) => run_setup().await,
        None => run_create_issue().await,
    }
}