// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

use crate::config::OS::{LINUX, MACOS, WINDOWS};
use crate::shell::run_shell_command_by_os;
use crate::{
    ARCH_ARM7L, Command, ENV_PROCESSOR_ARCHITECTURE, REQUEST_TIMEOUT_SEC, UNAME_COMMAND,
    default_cache_folder, format_one_arg, path_to_string,
};
use crate::{ARCH_ARM64, ARCH_X64, ARCH_X86, TTL_SEC};
use anyhow::Error;
use anyhow::anyhow;
use std::cell::RefCell;
use std::env;
use std::env::consts::OS;
use std::fs::read_to_string;
use std::path::Path;
use toml::Table;
#[cfg(windows)]
use winapi::um::sysinfoapi::{GetNativeSystemInfo, SYSTEM_INFO};
#[cfg(windows)]
use winapi::um::winnt::{
    PROCESSOR_ARCHITECTURE_AMD64, PROCESSOR_ARCHITECTURE_ARM, PROCESSOR_ARCHITECTURE_ARM64,
    PROCESSOR_ARCHITECTURE_IA64, PROCESSOR_ARCHITECTURE_INTEL,
};

thread_local!(static CACHE_PATH: RefCell<String> = RefCell::new(path_to_string(&default_cache_folder())));

pub const CONFIG_FILE: &str = "se-config.toml";
pub const ENV_PREFIX: &str = "SE_";
pub const VERSION_PREFIX: &str = "-version";
pub const PATH_PREFIX: &str = "-path";
pub const MIRROR_PREFIX: &str = "-mirror-url";
pub const CACHE_PATH_KEY: &str = "cache-path";

pub struct ManagerConfig {
    pub cache_path: String,
    pub fallback_driver_from_cache: bool,
    pub browser_version: String,
    pub driver_version: String,
    pub browser_path: String,
    pub driver_mirror_url: String,
    pub browser_mirror_url: String,
    pub os: String,
    pub arch: String,
    pub proxy: String,
    pub timeout: u64,
    pub ttl: u64,
    pub offline: bool,
    pub force_browser_download: bool,
    pub avoid_browser_download: bool,
    pub language_binding: String,
    pub selenium_version: String,
    pub avoid_stats: bool,
    pub skip_driver_in_path: bool,
    pub skip_browser_in_path: bool,
}

impl ManagerConfig {
    pub fn default(browser_name: &str, driver_name: &str) -> ManagerConfig {
        let cache_path = StringKey(vec![CACHE_PATH_KEY], &read_cache_path()).get_value();

        let self_os = OS;
        let self_arch = if WINDOWS.is(self_os) {
            let mut _architecture = env::var(ENV_PROCESSOR_ARCHITECTURE).unwrap_or_default();
            #[cfg(windows)]
            {
                if _architecture.is_empty() {
                    _architecture = get_win_os_architecture();
                }
            }
            if _architecture.contains("32") {
                ARCH_X86.to_string()
            } else if _architecture.contains("ARM") {
                ARCH_ARM64.to_string()
            } else {
                ARCH_X64.to_string()
            }
        } else {
            let uname_a_command = Command::new_single(format_one_arg(UNAME_COMMAND, "a"));
            if run_shell_command_by_os(self_os, uname_a_command)
                .unwrap_or_default()
                .to_ascii_lowercase()
                .contains(ARCH_ARM64)
            {
                ARCH_ARM64.to_string()
            } else {
                let uname_m_command = Command::new_single(format_one_arg(UNAME_COMMAND, "m"));
                run_shell_command_by_os(self_os, uname_m_command).unwrap_or_default()
            }
        };

        let browser_version_label = concat(browser_name, VERSION_PREFIX);
        let driver_version_label = concat(driver_name, VERSION_PREFIX);
        let browser_path_label = concat(browser_name, PATH_PREFIX);
        let driver_mirror_label = concat(driver_name, MIRROR_PREFIX);
        let browser_mirror_label = concat(browser_name, MIRROR_PREFIX);

        ManagerConfig {
            cache_path,
            fallback_driver_from_cache: true,
            browser_version: StringKey(vec!["browser-version", &browser_version_label], "")
                .get_value(),
            driver_version: StringKey(vec!["driver-version", &driver_version_label], "")
                .get_value(),
            browser_path: StringKey(vec!["browser-path", &browser_path_label], "").get_value(),
            driver_mirror_url: StringKey(vec!["driver-mirror-url", &driver_mirror_label], "")
                .get_value(),
            browser_mirror_url: StringKey(vec!["browser-mirror-url", &browser_mirror_label], "")
                .get_value(),
            os: StringKey(vec!["os"], self_os).get_value(),
            arch: StringKey(vec!["arch"], self_arch.as_str()).get_value(),
            proxy: StringKey(vec!["proxy"], "").get_value(),
            timeout: IntegerKey("timeout", REQUEST_TIMEOUT_SEC).get_value(),
            ttl: IntegerKey("ttl", TTL_SEC).get_value(),
            offline: BooleanKey("offline", false).get_value(),
            force_browser_download: BooleanKey("force-browser-download", false).get_value(),
            avoid_browser_download: BooleanKey("avoid-browser-download", false).get_value(),
            language_binding: StringKey(vec!["language-binding"], "").get_value(),
            selenium_version: StringKey(vec!["selenium-version"], "").get_value(),
            avoid_stats: BooleanKey("avoid-stats", false).get_value(),
            skip_driver_in_path: BooleanKey("skip-driver-in-path", false).get_value(),
            skip_browser_in_path: BooleanKey("skip-browser-in-path", false).get_value(),
        }
    }
}

#[allow(dead_code)]
#[allow(clippy::upper_case_acronyms)]
#[derive(Hash, Eq, PartialEq, Debug)]
pub enum OS {
    WINDOWS,
    MACOS,
    LINUX,
}

impl OS {
    pub fn to_str_vector(&self) -> Vec<&str> {
        match self {
            WINDOWS => vec!["windows", "win"],
            MACOS => vec!["macos", "mac"],
            LINUX => vec!["linux", "gnu/linux"],
        }
    }

    pub fn is(&self, os: &str) -> bool {
        self.to_str_vector()
            .contains(&os.to_ascii_lowercase().as_str())
    }
}

pub fn str_to_os(os: &str) -> Result<OS, Error> {
    if WINDOWS.is(os) {
        Ok(WINDOWS)
    } else if MACOS.is(os) {
        Ok(MACOS)
    } else if LINUX.is(os) {
        Ok(LINUX)
    } else {
        Err(anyhow!(format!("Invalid operating system: {os}")))
    }
}

#[allow(dead_code)]
#[allow(clippy::upper_case_acronyms)]
pub enum ARCH {
    X32,
    X64,
    ARM64,
    ARMV7,
}

impl ARCH {
    pub fn to_str_vector(&self) -> Vec<&str> {
        match self {
            ARCH::X32 => vec![ARCH_X86, "i386", "x32"],
            ARCH::X64 => vec![ARCH_X64, "amd64", "x64", "i686", "ia64"],
            ARCH::ARM64 => vec![ARCH_ARM64, "aarch64", "arm"],
            ARCH::ARMV7 => vec![ARCH_ARM7L, "armv7l"],
        }
    }

    pub fn is(&self, arch: &str) -> bool {
        self.to_str_vector()
            .contains(&arch.to_ascii_lowercase().as_str())
    }
}

pub struct StringKey<'a>(pub Vec<&'a str>, pub &'a str);

impl StringKey<'_> {
    pub fn get_value(&self) -> String {
        let config = get_config().unwrap_or_default();
        let keys = self.0.to_owned();
        let default_value = self.1.to_owned();
        let mut result;
        for key in keys {
            if config.contains_key(key) {
                result = config[key].as_str().unwrap().to_string()
            } else {
                result = env::var(get_env_name(key)).unwrap_or_default()
            }
            if key.eq(CACHE_PATH_KEY) {
                // The configuration key for the cache path ("cache-path") is special because
                // the rest of the configuration values depend on this value (since the
                // configuration file is stored in the cache path). Therefore, this value needs
                // to be discovered in the first place and stored globally (on CACHE_PATH)
                return check_cache_path(result, default_value);
            }
            if !result.is_empty() {
                return result;
            }
        }
        default_value
    }
}

pub struct IntegerKey<'a>(pub &'a str, pub u64);

impl IntegerKey<'_> {
    pub fn get_value(&self) -> u64 {
        let config = get_config().unwrap_or_default();
        let key = self.0;
        if config.contains_key(key) {
            config[key].as_integer().unwrap() as u64
        } else {
            env::var(get_env_name(key))
                .unwrap_or_default()
                .parse::<u64>()
                .unwrap_or_else(|_| self.1.to_owned())
        }
    }
}

pub struct BooleanKey<'a>(pub &'a str, pub bool);

impl BooleanKey<'_> {
    pub fn get_value(&self) -> bool {
        let config = get_config().unwrap_or_default();
        let key = self.0;
        if config.contains_key(key) {
            config[key].as_bool().unwrap()
        } else {
            env::var(get_env_name(key))
                .unwrap_or_default()
                .parse::<bool>()
                .unwrap_or_else(|_| self.1.to_owned())
        }
    }
}

fn get_env_name(suffix: &str) -> String {
    let suffix_uppercase: String = suffix.replace('-', "_").to_uppercase();
    concat(ENV_PREFIX, suffix_uppercase.as_str())
}

fn get_config() -> Result<Table, Error> {
    let cache_path = read_cache_path();
    let config_path = Path::new(&cache_path).to_path_buf().join(CONFIG_FILE);
    Ok(read_to_string(config_path)?.parse()?)
}

fn concat(prefix: &str, suffix: &str) -> String {
    let mut version_label: String = prefix.to_owned();
    version_label.push_str(suffix);
    version_label
}

fn check_cache_path(value_in_config_or_env: String, default_value: String) -> String {
    let return_value = if !value_in_config_or_env.is_empty() {
        value_in_config_or_env
    } else if !default_value.is_empty() {
        default_value
    } else {
        read_cache_path()
    };
    write_cache_path(return_value.clone());
    return_value
}

fn write_cache_path(cache_path: String) {
    CACHE_PATH.with(|value| {
        *value.borrow_mut() = cache_path;
    });
}

fn read_cache_path() -> String {
    let mut cache_path: String = path_to_string(&default_cache_folder());
    CACHE_PATH.with(|value| {
        let path: String = (&*value.borrow().to_string()).into();
        if !path.is_empty() {
            cache_path = path;
        }
    });
    cache_path
}

#[cfg(windows)]
fn get_win_os_architecture() -> String {
    unsafe {
        let mut system_info: SYSTEM_INFO = std::mem::zeroed();
        GetNativeSystemInfo(&mut system_info);

        match system_info.u.s() {
            si if si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 => "64-bit",
            si if si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL => "32-bit",
            si if si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM => "ARM",
            si if si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64 => "ARM64",
            si if si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 => "Itanium-based",
            _ => "Unknown",
        }
        .to_string()
    }
}
