memoscli 0.1.0

A command-line tool to manage memos
use crate::models::{CreateMemoRequest, ListMemosResponse, Memo};
use anyhow::Result;
use reqwest::Client;

#[derive(Clone)]
pub struct MemosClient {
    client: Client,
    base_url: String,
    user_token: String,
}

impl MemosClient {
    pub fn new(base_url: &str, user_token: &str) -> Result<Self> {
        let base_url = base_url.trim_end_matches('/');
        Ok(Self {
            client: Client::new(),
            base_url: base_url.to_string(),
            user_token: user_token.to_string(),
        })
    }

    pub async fn create_memo(&self, content: &str, visibility: Option<&str>) -> Result<Memo> {
        let url = format!("{}/api/v1/memos", self.base_url);

        let visibility_str = visibility.map(|v| {
            if v.starts_with("VISIBILITY_") {
                v.to_string()
            } else {
                format!("VISIBILITY_{}", v.to_uppercase())
            }
        });

        let request = CreateMemoRequest {
            content: content.to_string(),
            visibility: visibility_str,
        };

        let response = self
            .client
            .post(&url)
            .header("Authorization", format!("Bearer {}", self.user_token))
            .header("Content-Type", "application/json")
            .json(&request)
            .send()
            .await?;

        if !response.status().is_success() {
            let status = response.status();
            let error_text = response.text().await.unwrap_or_default();
            anyhow::bail!("Failed to create memo: {} - {}", status, error_text);
        }

        let mut memo: Memo = response.json().await?;
        memo.id = Memo::extract_id(&memo.name);
        Ok(memo)
    }

    pub async fn list_memos(&self, limit: Option<i32>, offset: Option<i32>) -> Result<Vec<Memo>> {
        let url = format!("{}/api/v1/memos", self.base_url);

        let mut request = self
            .client
            .get(&url)
            .header("Authorization", format!("Bearer {}", self.user_token));

        if let Some(l) = limit {
            request = request.query(&[("limit", l.to_string())]);
        }
        if let Some(o) = offset {
            request = request.query(&[("offset", o.to_string())]);
        }

        let response = request.send().await?;

        if !response.status().is_success() {
            let status = response.status();
            let error_text = response.text().await.unwrap_or_default();
            anyhow::bail!("Failed to list memos: {} - {}", status, error_text);
        }

        let result: ListMemosResponse = response.json().await?;
        Ok(result.memos)
    }
}