1use crate::auth::{self, Provider};
4use crate::core::error::Result;
5use dialoguer::{theme::ColorfulTheme, Select};
6
7pub async fn run() -> Result<()> {
9 let providers = auth::get_authenticated_providers();
11
12 if !providers.is_empty() {
13 println!("Already logged in with:");
14 for p in &providers {
15 match p {
16 Provider::Anthropic => println!(" - Claude (Anthropic)"),
17 Provider::Google => println!(" - Gemini (Google)"),
18 }
19 }
20 println!("\nTo switch providers, run 'greppy logout' first.");
21 return Ok(());
22 }
23
24 let options = &["Claude (Anthropic) - OAuth", "Gemini (Google) - OAuth"];
26
27 let selection = Select::with_theme(&ColorfulTheme::default())
28 .with_prompt("Choose AI provider")
29 .items(options)
30 .default(0)
31 .interact()
32 .map_err(|e| crate::core::error::Error::DaemonError {
33 message: format!("Selection failed: {}", e),
34 })?;
35
36 match selection {
37 0 => {
38 println!("\nAuthenticating with Claude...\n");
39 auth::login_anthropic().await?;
40 }
41 1 => {
42 println!("\nAuthenticating with Google...\n");
43 auth::login_google().await?;
44 }
45 _ => unreachable!(),
46 }
47
48 println!("\nYou can now use semantic search:");
49 println!(" greppy search \"your query\"");
50
51 Ok(())
52}
53
54pub fn logout() -> Result<()> {
56 let providers = auth::get_authenticated_providers();
57
58 if providers.is_empty() {
59 println!("Not logged in to any provider.");
60 return Ok(());
61 }
62
63 println!("Logging out from:");
64 for p in &providers {
65 match p {
66 Provider::Anthropic => println!(" - Claude (Anthropic)"),
67 Provider::Google => println!(" - Gemini (Google)"),
68 }
69 }
70
71 auth::logout()?;
72 println!("\nSuccessfully logged out.");
73 Ok(())
74}
75
76pub fn is_authenticated() -> bool {
78 !auth::get_authenticated_providers().is_empty()
79}
80
81pub fn get_preferred_provider() -> Option<Provider> {
83 let providers = auth::get_authenticated_providers();
84 if providers.contains(&Provider::Anthropic) {
85 Some(Provider::Anthropic)
86 } else if providers.contains(&Provider::Google) {
87 Some(Provider::Google)
88 } else {
89 None
90 }
91}