1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#[macro_use]
extern crate prettytable;

use crate::args::commands::{Commands, JirustCliArgs};

use crate::executors::jira_commands_executors::jira_version_executor::VersionExecutor;
use clap::Parser;
use config::config_file::ConfigFile;
use executors::config_executor::ConfigExecutor;
use executors::jira_commands_executors::jira_project_executor::ProjectExecutor;
use executors::jira_commands_executors::ExecJiraCommand;
use std::env::Args;
use std::io::{Error, ErrorKind};

pub mod args;
pub mod config;
pub mod executors;
pub mod runners;
pub mod utils;

/// Manages the loading of the CLI configuration
///
/// # Arguments
/// * `config_file_path` - The path to the configuration file
/// * `args` - The arguments passed to the CLI
///
/// # Returns
/// * A tuple containing the configuration file and the command to execute
///
/// # Errors
/// * If the configuration file is not found
/// * If the configuration file is missing mandatory fields
///
/// # Examples
///
/// ```no_run
/// use jirust_cli::manage_config;
/// use jirust_cli::config::config_file::ConfigFile;
/// use jirust_cli::args::commands::Commands;
///
/// # fn main() -> Result<(), std::io::Error> {
/// let config_file_path = String::from("config.json");
/// let args = std::env::args();
/// let (cfg_data, command) = manage_config(config_file_path, args)?;
/// # Ok(())
/// # }
/// ```
pub fn manage_config(
    config_file_path: String,
    args: Args,
) -> Result<(ConfigFile, Commands), Error> {
    let opts = match JirustCliArgs::try_parse_from(args) {
        Ok(opts) => opts,
        Err(err) => {
            eprintln!("Error: {}", err);
            err.exit();
        }
    };
    let cfg_data = match ConfigFile::read_from_file(config_file_path.as_str()) {
        Ok(cfg) => cfg,
        Err(_) => {
            return Err(Error::new(
                ErrorKind::NotFound,
                "Missing basic configuration, setup mandatory!",
            ))
        }
    };
    if cfg_data.get_auth_key().is_empty() || cfg_data.get_jira_url().is_empty() {
        Err(Error::new(
            ErrorKind::NotFound,
            "Missing basic configuration, setup mandatory!",
        ))
    } else {
        Ok((cfg_data, opts.subcmd))
    }
}

/// Processes the command passed to the CLI
///
/// # Arguments
/// * `command` - The command to execute
/// * `config_file_path` - The path to the configuration file
/// * `cfg_data` - The configuration file data
///
/// # Returns
/// * A Result containing the result of the command execution
///
/// # Errors
/// * If the command execution fails
///
/// # Examples
///
/// ```no_run
/// use jirust_cli::process_command;
/// use jirust_cli::config::config_file::ConfigFile;
/// use jirust_cli::args::commands::{Commands, VersionArgs, VersionActionValues};
///
/// # fn main() -> Result<(), std::io::Error> {
/// let config_file_path = String::from("config.json");
/// let args = VersionArgs {
///   version_act: VersionActionValues::List,
///   project: "project_key".to_string(),
///   project_id: None,
///   version_id: Some("97531".to_string()),
///   version_name: Some("version_name".to_string()),
///   version_description: Some("version_description".to_string()),
///   version_start_date: None,
///   version_release_date: None,
///   version_archived: None,
///   version_released: Some(true),
///   version_page_size: None,
///   version_page_offset: None,
/// };
///
/// let result = process_command(Commands::Version(args), config_file_path, ConfigFile::default());
/// # Ok(())
/// # }
/// ```
pub async fn process_command(
    command: Commands,
    config_file_path: String,
    cfg_data: ConfigFile,
) -> Result<(), Box<dyn std::error::Error>> {
    match command {
        Commands::Config(args) => {
            let config_executor = ConfigExecutor::new(config_file_path, args.cfg_act);
            config_executor.exec_config_command(cfg_data).await?
        }
        Commands::Version(args) => {
            let version_executor = VersionExecutor::new(cfg_data, args.version_act, args);
            version_executor.exec_jira_command().await?
        }
        Commands::Project(args) => {
            let project_executor = ProjectExecutor::new(cfg_data, args.project_act, args);
            project_executor.exec_jira_command().await?
        }
    }
    Ok(())
}