// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use anyhow::{anyhow, Result};
use regex::Regex;
use std::{collections::HashMap, path::PathBuf, time::Duration};

pub type SteamAppId = u64;

#[cfg(not(test))]
pub const UNMOUNTER_INTERVAL: Duration = Duration::from_millis(1000);
#[cfg(test)]
pub const UNMOUNTER_INTERVAL: Duration = Duration::from_millis(10);

pub const DLC_HANDLER_INTERVAL: Duration = Duration::from_millis(1000);
pub const MAX_CONCURRENT_DLC_INSTALLS: usize = 1;
// Limit the number of DLC installation queue to:
// - Prevent 'hogging' DlcService. DlcService does not support parallel
//   downloads or queues yet.
// - Prevent the user from increasing shadercached memory footprint infinitely.
//   VM user can queue shader cache DLC installations by design.
pub const MAX_INSTALL_QUEUE_SIZE: usize = 5;

pub const PRECOMPILED_CACHE_DIR: &str = "precompiled_cache";

// GPU device id reported by the pcie ID
#[cfg(test)]
lazy_static! {
    pub static ref IMAGE_LOADER: PathBuf = tempfile::tempdir().unwrap().into_path();
    pub static ref CRYPTO_HOME: PathBuf = tempfile::tempdir().unwrap().into_path();
    pub static ref GPU_DEVICE_ID: u16 = 0x9a40;
}

#[cfg(not(test))]
lazy_static! {
    pub static ref IMAGE_LOADER: PathBuf = std::path::Path::new("/run/imageloader").to_path_buf();
    pub static ref CRYPTO_HOME: PathBuf =
        std::path::Path::new("/run/daemon-store/shadercached").to_path_buf();
    pub static ref GPU_DEVICE_ID: u16 = get_gpu_device_id().unwrap_or(0);
}

lazy_static! {
    pub static ref GPU_DEVICE_DLC_VARIANT: &'static str = {
        // These suffixes are non-technical names to create buckets for each
        // device id variants per board.
        const DLC_VARIANT_AXE: &str = "-axe";
        const DLC_VARIANT_BATRIDER: &str = "-batrider";
        const DLC_VARIANT_CLINKZ: &str = "-clinkz";
        const DLC_VARIANT_DAZZLE: &str = "-dazzle";
        const DLC_VARIANT_ENIGMA: &str = "-enigma";
        const DLC_VARIANT_GRIMSTROKE: &str = "-grimstroke";

        let variant_mapping: HashMap<u16, &str> = HashMap::from([
            // axe variant
            (u16::from_str_radix("9a49", 16).unwrap(), DLC_VARIANT_AXE),  // volteer
            (u16::from_str_radix("46a6", 16).unwrap(), DLC_VARIANT_AXE),  // brya
            (u16::from_str_radix("46d0", 16).unwrap(), DLC_VARIANT_AXE),  // nissa
            (u16::from_str_radix("9b41", 16).unwrap(), DLC_VARIANT_AXE),  // hatch
            (u16::from_str_radix("7d45", 16).unwrap(), DLC_VARIANT_AXE),  // rex

            // batrider variant
            (u16::from_str_radix("9a40", 16).unwrap(), DLC_VARIANT_BATRIDER),  // volteer
            (u16::from_str_radix("46b3", 16).unwrap(), DLC_VARIANT_BATRIDER),  // brya
            (u16::from_str_radix("9bcc", 16).unwrap(), DLC_VARIANT_BATRIDER),  // hatch

            // clinkz variant
            (u16::from_str_radix("9a78", 16).unwrap(), DLC_VARIANT_CLINKZ),  // volteer
            (u16::from_str_radix("a7a0", 16).unwrap(), DLC_VARIANT_CLINKZ),  // brya
            (u16::from_str_radix("9bca", 16).unwrap(), DLC_VARIANT_CLINKZ),  // hatch

            // dazzle variant
            (u16::from_str_radix("a7a9", 16).unwrap(), DLC_VARIANT_DAZZLE),  // brya
            (u16::from_str_radix("9bac", 16).unwrap(), DLC_VARIANT_DAZZLE),  // hatch

            // enigma variant
            (u16::from_str_radix("a7a1", 16).unwrap(), DLC_VARIANT_ENIGMA),  // brya
            (u16::from_str_radix("9b21", 16).unwrap(), DLC_VARIANT_ENIGMA),  // hatch

            // grimstroke variant
            (u16::from_str_radix("46a8", 16).unwrap(), DLC_VARIANT_GRIMSTROKE),  // brya
        ]);

        // If no device id is detected or not found in |variant_mapping|,
        // shadercached should attempt to install axe variant.
        variant_mapping.get(&*GPU_DEVICE_ID).unwrap_or(&DLC_VARIANT_AXE)
    };

    pub static ref BOOT_ID: String = {
        const BOOT_ID_FILE: &str = "/proc/sys/kernel/random/boot_id";
        let contents = std::fs::read(BOOT_ID_FILE).expect(
            "Expected to be able to read the boot id file");
        hex::encode(openssl::sha::sha256(&contents))
    };

    pub static ref OS_BUILD_ID: String = {
        if let Ok(os_release) = sys_info::linux_os_release() {
            if let Some(build_id) = os_release.build_id {
                return hex::encode(openssl::sha::sha256(build_id.as_bytes()))
            }
        }

        // Fall back to boot id
        BOOT_ID.to_string()
    };
}

pub fn steam_app_id_to_dlc(steam_app_id: SteamAppId) -> String {
    format!(
        "borealis-shader-cache-{}-dlc{}",
        steam_app_id, *GPU_DEVICE_DLC_VARIANT
    )
}

pub fn dlc_to_steam_app_id(dlc_name: &str) -> Result<SteamAppId> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"borealis-shader-cache-([0-9]+)-dlc(-.+)?").unwrap();
    }
    if let Some(capture) = RE.captures(dlc_name) {
        if let Some(steam_app_id_match) = capture.get(1) {
            return steam_app_id_match
                .as_str()
                .parse::<SteamAppId>()
                .map_err(|e| anyhow!(e));
        }
    }
    Err(anyhow!("Not a valid DLC"))
}

#[cfg(not(test))]
fn get_gpu_device_id() -> Result<u16> {
    use log::warn;
    use std::process::{Command, Stdio};
    // This function is called only once to initialize pub lazy static constant
    // GPU_DEVICE_ID, so we don't need to make the Regex object static.
    let regex = Regex::new(r"\[([0-9a-f]{4})\]").unwrap();
    let output = Command::new("lspci")
        .args(["-nn", "-d", "::0300", "-mm"]) // -d ::0300 returns only VGA device
        .stdout(Stdio::piped())
        .output()?;
    let vga_pcie_info = String::from_utf8(output.stdout)?;

    // Match the regex pattern for all occurrences
    let mut all_captures = regex.captures_iter(&vga_pcie_info);
    // Get the 3rd match, which has the GPU PCIE device ID
    if let Some(capture) = all_captures.nth(2) {
        // For the capture (ex. [abcd]), get the first inner match
        if let Some(device_id_match) = capture.get(1) {
            if let Ok(id) = u16::from_str_radix(device_id_match.as_str(), 16) {
                return Ok(id);
            } else {
                warn!("Failed to parse device ID: {}", device_id_match.as_str());
            }
        } else {
            warn!("Unable to extract PCI device ID, {}", vga_pcie_info);
        }
    } else {
        warn!("Unexpected VGA PCI information, {}", vga_pcie_info);
    }

    Err(anyhow!("Unable to determine PCI device ID!"))
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_steam_app_id_to_dlc() {
        assert_eq!(
            super::steam_app_id_to_dlc(32),
            "borealis-shader-cache-32-dlc-batrider"
        );
        assert_eq!(
            super::steam_app_id_to_dlc(123),
            "borealis-shader-cache-123-dlc-batrider"
        );
        assert_eq!(
            super::steam_app_id_to_dlc(0000),
            "borealis-shader-cache-0-dlc-batrider"
        );
    }

    #[test]
    fn test_dlc_to_steam_app_id() {
        assert_eq!(
            super::dlc_to_steam_app_id("borealis-shader-cache-32-dlc-axe").unwrap(),
            32
        );
        assert_eq!(
            super::dlc_to_steam_app_id("borealis-shader-cache-000-dlc-batrider").unwrap(),
            0
        );
        assert_eq!(
            super::dlc_to_steam_app_id("borealis-shader-cache-000-dlc").unwrap(),
            0
        );
        assert!(super::dlc_to_steam_app_id("borealis-shader-cache-213").is_err());
        assert!(super::dlc_to_steam_app_id("213-dlc").is_err());
        assert!(super::dlc_to_steam_app_id("not-a-valid-one").is_err());
        assert!(super::dlc_to_steam_app_id("borealis-dlc").is_err());
        assert!(super::dlc_to_steam_app_id("borealis-shader-cache-two-dlc").is_err());
    }
}
