revq 0.1.1

Review and query your pull requests
use anyhow::{Context, Result};
use colored::*;
use directories::BaseDirs;
use inquire::{Confirm, Text};
use serde::Serialize;
use std::fs;
use std::io::Write;
use std::path::PathBuf;
use std::thread;
use std::time::Duration;
use toml;

#[derive(Serialize)]
struct OrgSet {
    organization: Option<String>,
    always: bool,
}

#[derive(Serialize)]
struct UserInfo {
    username: String,
    token: String,
    organization_settings: Option<OrgSet>,
}

pub fn show_spinner() {
    let spinner_chars = ["", "", "", "", "", "", "", ""];
    let spinner_interval = Duration::from_millis(50);

    for _ in 0..3 {
        for &char in &spinner_chars {
            print!("\r{}", char.blue().bold());
            std::io::stdout().flush().expect("Failed to flush stdout");
            thread::sleep(spinner_interval);
        }
    }
}

fn prompt_for_user_info() -> Result<UserInfo> {
    let username = Text::new("Please enter your GitHub username:")
        .prompt()
        .context("Failed to get the username")?;

    let token = Text::new("Please enter your Github token:")
        .prompt()
        .context("Failed to get the token")?;

    let org_input = Text::new("Enter your Github organization name (optional):")
        .prompt_skippable()
        .context("Failed to get the organization")?;

    let organization = org_input.filter(|s| !s.is_empty());

    let organization_settings = if organization.is_some() {
        let always = Confirm::new("Do you want to always use the organization context by default?")
            .with_default(false)
            .prompt()
            .context("Error while prompting for always use org setting")?;

        Some(OrgSet {
            organization,
            always,
        })
    } else {
        None
    };

    Ok(UserInfo {
        username,
        token,
        organization_settings,
    })
}

pub fn init(force: bool) -> Result<InitResult> {
    let base_dirs = BaseDirs::new().context("Failed to get base directories")?;
    let config_dir = base_dirs.config_dir().join("revq");
    let config_file = config_dir.join("config.toml");

    if config_file.exists() && !force {
        return Ok(InitResult::Skipped(config_file));
    }

    let user_info = prompt_for_user_info()?;

    let toml_output = toml::to_string(&user_info).context("Failed to serialize to TOML")?;

    fs::create_dir_all(&config_dir).context("Failed to create config directory")?;
    fs::write(&config_file, toml_output).context("Failed to write config file")?;

    Ok(InitResult::Completed(config_file))
}

pub enum InitResult {
    Completed(PathBuf),
    Skipped(PathBuf),
}