#![deny(rust_2018_idioms)]
#![allow(clippy::single_component_path_imports)]
#![allow(clippy::type_complexity)]
#![cfg_attr(docsrs, allow(unused_attributes))]
#![recursion_limit = "1024"]
#![warn(
    missing_debug_implementations,
    missing_docs,
    rust_2018_idioms,
    unreachable_pub
)]
//! [![](https://gitlab.com/andrew_ryan/doe/-/raw/master/doe.svg)](https://docs.rs/doe)

#![doc(
    html_logo_url = "https://gitlab.com/andrew_ryan/doe/-/raw/master/html_logo.svg",
    html_favicon_url = "https://gitlab.com/andrew_ryan/doe/-/raw/master/html_favicon.svg"
)]

//!
//! doe is a versatile Rust crate that significantly enhances the development workflow by offering an extensive collection of useful macros and utility functions. It streamlines common tasks and provides convenient features for clipboard management, state management, keyboard input, and mouse interaction. Additionally, doe includes robust cryptographic functions, enabling developers to easily integrate secure encryption, decryption, and hashing capabilities into their applications, ensuring data integrity and confidentiality.
//!
//!# Features
//!### ctf
//!```sh
//!cargo add doe -F ctf
//!```
//!allow you to perform various operations with ease, such as string manipulation, urlencode urldecode,hex encode decode,base43 encode decode, and error management.
//!### clip
//!```sh
//!cargo add doe -F clip
//!```
//!simplifies clipboard management, enabling you to effortlessly interact with the system clipboard.
//!### mouse
//!```sh
//!cargo add doe -F mouse
//!```
//!offers intuitive and easy-to-use functions for simulating mouse actions.
//!### keyboard
//!```sh
//!cargo add doe -F keyboard
//!```
//!offers simulating keyboard input action with easy-to-use functions.
//!### kcm
//!kcm is short feature for keyboard clipboard mouse together
//!```sh
//!cargo add doe -F kcm
//!```
//!### xlsx
//!read edit write xlsx file
//!```sh
//!cargo add doe -F xlsx
//!```
//!### docx
//!read edit docx file
//!```sh
//!cargo add doe -F docx
//!```
//!### date
//!get and read edit date string
//!```sh
//!cargo add doe -F date
//!```
//! ### screenshot
//! screenshot and get hex from screenshot image
//!```sh
//!cargo add doe -F screenshot
//!```
//! ### images
//! resize add paddings,convert image format
//!```sh
//!cargo add doe -F images
//!```
//! ### crypto
//! includes robust cryptographic functions
//!```sh
//!cargo add doe -F crypto
//!```

/// clipboard module provides functions and structs related to clipboard operations. It allows the user to copy and paste data between the application and the clipboard.
pub mod clipboard;
/// color module contains functions for converting grb format to hex and hex to grb format
pub mod color;
///const data
pub mod consts;
/// ctf module provides utility functions like `permutations`,`hex_encode`,`hex_decode`,`base64_encode`,`base64_decode`,`php_urlencode`,`php_urldecode`.
pub mod ctf;
/// date module contains functions for get now,get_recent_seven_days,normal_date_to_excel_date,excel_date_to_normal_date
pub mod date;
///xlsx module contains functions for reading editing docx file
pub mod docx;
/// The file system (fs) module provides functions and structs for performing operations on the file system. It includes functions for reading, writing, creating, and deleting files and directories.
pub mod fs;
///images module contains functions resize add paddings,convert image format
pub mod images;
///keyboard module contains functions and structs related to keyboard input. It allows the user to simulate keyboard input, capture keystrokes, and perform other keyboard-related operations.
pub mod keyboard;
///macros module contains all utility macros for development
pub mod macros;
/// mouse module contains functions and structs related to mouse input. It allows the user to simulate mouse input, capture mouse movements and clicks, and perform other mouse-related operations.
pub mod mouse;
/// get all process (name,pid) and kill process by name or pid
pub mod process;
/// A Linear Congruential Generator (LCG) is a simple type of random number generator that produces a sequence of pseudo-random numbers based on a linear recurrence relation.
pub mod rand;
///screenshot module contains functions for screenshot and get hex from screenshot image
pub mod screenshot;
///structs module contains definitions of custom data structures like `Bfn`, `Bts`, `waker_fn`.
pub mod structs;
/// timer module provides functions and structs for creating and managing timers. It allows the user to schedule tasks to be executed at a specific time or interval.
pub mod timer;
///traits module contains trait definitions that define shared behavior and functions
pub mod traits;
///xlsx module contains functions and structs for reading, writing, and manipulating Excel files in the XLSX format.
pub mod xlsx;
///zoml module contains functions for converting data between the ZOML format and CSV format.
pub mod zoml;
///json module contains functions for reading, writing, and manipulating JSON files or content.
pub mod json;
///reqwest module is easy way to use reqwest crate for http requests
pub mod http;
///crypto module contains AES,RSA,sha1,sha2,sha3,md5,blake3 functions
pub mod crypto;
///async_runtime module contains async runtime
pub mod async_runtime;


pub use consts::consts::*;
pub use fs::fs::*;
pub use macros::macros::*;
pub use rand::rand::*;
pub use structs::structs::*;
pub use timer::impl_timer::*;
pub use traits::traits::*;
pub use zoml::zoml::*;

use std::sync::Arc;
///
pub type DynError<T> = Result<T, Box<dyn std::error::Error>>;
///Rust is a wrapper for the standard library's std::process::Command function, which is used to execute external commands
///```rust
///     doe::system("ls");
///     doe::system("ls -a");
/// ```
///
/// # Examples
///
/// ```ignore
/// use doe::system;
/// system("ls -a");
/// ```
pub fn system(command: impl ToString) -> std::io::Result<()> {
    use std::process::Command;
    if cfg!(target_os = "windows") {
        if crate::has_powershell!() {
            Command::new("powershell")
                .arg("-Command")
                .arg(&command.to_string())
                .status()?;
        } else {
            Command::new("cmd")
                .arg("/c")
                .arg(&command.to_string())
                .status()?;
        }
    } else {
        Command::new("sh")
            .arg("-c")
            .arg(&command.to_string())
            .status()?;
    }
    Ok(())
}
///lowercase_letters
pub fn lowercase_letters() -> Arc<str> {
    Arc::from("abcdefghijklmnopqrstuvwxyz")
}
///uppercase_letters
pub fn uppercase_letters() -> Arc<str> {
    Arc::from("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
}
///digits
pub fn digits() -> Arc<str> {
    Arc::from("0123456789")
}
///letters_and_digits
pub fn letters_and_digits() -> Arc<str> {
    Arc::from(format!("{}{}{}", lowercase_letters(), uppercase_letters(), digits()).as_ref())
}

///The Vec sort all elements can be repeated to define the longest shortest size
/// ```ignore
///fn main() {
///     use doe::DebugPrint;
///     use doe::utils::generate_all_possible_vec;
///    let v  = generate_all_possible_vec(&vec![1,2,3],1,2);
///    v.dprintln();//[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
///}
///```
pub fn generate_all_possible_vec<T: Clone>(
    elements: &[T],
    min_len: usize,
    max_len: usize,
) -> Vec<Vec<T>> {
    let mut result = Vec::new();
    for len in min_len..=max_len {
        let mut indices = vec![0; len];
        let mut done = false;
        while !done {
            let permutation = indices.iter().map(|&i| elements[i].clone()).collect();
            result.push(permutation);
            done = true;
            for i in (0..len).rev() {
                indices[i] += 1;
                if indices[i] == elements.len() {
                    indices[i] = 0;
                } else {
                    done = false;
                    break;
                }
            }
        }
    }
    result
}
///permutations
/// ```ignore
///fn main() {
///    use doe::utils::permutations;
///    use doe::DebugPrint;
///    permutations("abc").dprintln();//["abc", "acb", "bac", "bca", "cba", "cab"]
///}
/// ```
pub fn permutations(alphabet: &str) -> Vec<String> {
    fn permute(chars: &mut [char], start: usize, result: &mut Vec<String>) {
        if start == chars.len() {
            result.push(chars.iter().collect());
        } else {
            for i in start..chars.len() {
                chars.swap(start, i);
                permute(chars, start + 1, result);
                chars.swap(start, i);
            }
        }
    }

    let mut result = Vec::new();
    let mut chars: Vec<char> = alphabet.chars().collect();
    permute(&mut chars, 0, &mut result);
    result
}
/// generate a random UUID
/// ```ignore
/// let s = uuid();
/// println!("{}", s);
/// ```
/// 
pub fn uuid() -> String {
    use std::time::{SystemTime, UNIX_EPOCH};
    fn gen()-> String{
        let start = SystemTime::now();
        let since_the_epoch = start.duration_since(UNIX_EPOCH).expect("Time went backwards");
        let timestamp = since_the_epoch.as_nanos();
    
        let uuid = format!("{:x}", timestamp);
    
        // Pad the UUID to ensure it has 32 characters
        let padded_uuid = format!("{:0>8}", uuid);
        // Insert hyphens at specific positions to form a UUID pattern
        format!(
            "{}",
            &padded_uuid[12..],
        )
    }
    format!("{}{}-{}-{}-{}-{}{}",gen(),gen(),gen(),gen(),gen(),gen(),gen())
}