use std::fs;
use std::path::Path;
use std::sync::Arc;
use anyhow::{anyhow, Context, Result};
use clap::Parser;
use skim::SkimItem;
use sysinfo::{Disk, DiskExt, RefreshKind, System, SystemExt};
use tuikit::prelude::{from_keyname, Event};
use tuikit::term::Term;
use crate::app::DisplaySettings;
use crate::app::Tab;
use crate::common::{args_is_empty, is_sudo_command, path_to_string};
use crate::common::{current_username, disk_space, filename_from_path, is_program_in_path};
use crate::common::{NVIM, SS};
use crate::config::{Bindings, Settings};
use crate::io::MIN_WIDTH_FOR_DUAL_PANE;
use crate::io::{execute_and_output, execute_without_output_with_path};
use crate::io::{execute_sudo_command_with_password, reset_sudo_faillock};
use crate::io::{Args, Kind};
use crate::io::{Internal, Opener};
use crate::modes::BlockDeviceAction;
use crate::modes::ContentWindow;
use crate::modes::FileKind;
use crate::modes::IsoDevice;
use crate::modes::Menu;
use crate::modes::MountCommands;
use crate::modes::MountRepr;
use crate::modes::Permissions;
use crate::modes::Preview;
use crate::modes::SelectableContent;
use crate::modes::ShellCommandParser;
use crate::modes::Skimer;
use crate::modes::Tree;
use crate::modes::Users;
use crate::modes::{copy_move, CopyMove};
use crate::modes::{regex_matcher, InputCompleted};
use crate::modes::{Display, Edit, InputSimple, NeedConfirmation};
use crate::modes::{PasswordKind, PasswordUsage};
use crate::{log_info, log_line};
use super::FirstLine;
/// Holds every mutable parameter of the application itself, except for
/// the "display" information.
/// It holds 2 tabs (left & right), even if only one can be displayed sometimes.
/// It knows which tab is selected, which files are flagged,
/// which jump target is selected, a cache of normal file colors,
/// if we have to display one or two tabs and if all details are shown or only
/// the filename.
/// Mutation of this struct are mostly done externally, by the event crate :
/// `crate::event_exec`.
pub struct Status {
/// Vector of `Tab`, each of them are displayed in a separate tab.
pub tabs: [Tab; 2],
/// Index of the current selected tab
pub index: usize,
/// Do we have to clear the screen ?
pub force_clear: bool,
/// terminal
pub term: Arc<Term>,
/// Info about the running machine. Only used to detect disks
/// and their mount points.
pub sys: System,
/// NVIM RPC server address
pub nvim_server: String,
/// The opener used by the application.
pub opener: Opener,
skimer: Option<Result<Skimer>>,
/// Navigable menu
pub menu: Menu,
/// Display settings
pub settings: DisplaySettings,
}
impl Status {
/// Creates a new status for the application.
/// It requires most of the information (arguments, configuration, height
/// of the terminal, the formated help string).
pub fn new(
height: usize,
term: Arc<Term>,
opener: Opener,
settings: &Settings,
) -> Result<Self> {
let args = Args::parse();
let nvim_server = args.server.clone();
let sys = System::new_with_specifics(RefreshKind::new().with_disks());
let force_clear = false;
let skimer = None;
let index = 0;
let users = Users::new();
let users2 = users.clone();
let mount_points = Self::disks_mounts(sys.disks());
let path = std::fs::canonicalize(Path::new(