use crate::dtos::bios::BiosInfo;
use crate::dtos::cpu::CpuInfo;
use crate::dtos::display::DisplayInfo;
use crate::dtos::gpu::GpuInfo;
use crate::dtos::HardWareInfo;
use crate::dtos::memory::MemoryInfo;
use crate::dtos::motherboard::MotherboardInfo;
use crate::dtos::os::OsInfo;
use crate::dtos::storage::DiskInfo;
use crate::enums::SystemFamily;
use crate::strategy::traits::HwStrategy;

#[cfg(target_os = "windows")]
pub mod windows;

#[cfg(target_os = "linux")]
pub mod linux;

pub mod macosx;
pub mod traits;

struct HwInfo {
    strategy: Box<dyn HwStrategy>,
}

impl HwInfo {
    fn new(strategy: Box<dyn HwStrategy>) -> HwInfo {
        HwInfo { strategy }
    }
}

impl HwStrategy for HwInfo {
    fn get_bios(&self) -> BiosInfo {
        self.strategy.get_bios()
    }

    fn get_cpu(&self) -> CpuInfo {
        self.strategy.get_cpu()
    }

	fn get_display(&self) -> Vec<DisplayInfo> {
		self.strategy.get_display()
	}

	fn get_gpu(&self) -> Vec<GpuInfo> {
		 self.strategy.get_gpu()
	}

	fn get_memory(&self) -> Vec<MemoryInfo> {
		self.strategy.get_memory()
	}

	fn get_motherboard(&self) -> MotherboardInfo {
		self.strategy.get_motherboard()
	}

	fn get_os(&self) -> OsInfo {
		self.strategy.get_os()
	}

	fn get_storage(&self) -> Vec<DiskInfo> {
		self.strategy.get_storage()
	}

	fn get_hw(&self) -> HardWareInfo {
		self.strategy.get_hw()
	}
}

pub fn get_hw_strategy(family: SystemFamily) -> Box<dyn HwStrategy> {
    match family {
        #[cfg(target_os = "windows")]
        SystemFamily::Windows => Box::new(windows::WindowsStrategy {}),
        #[cfg(target_os = "linux")]
        SystemFamily::Linux => Box::new(linux::LinuxStrategy {}),
        // SystemFamily::Macosx => Box::new(macosx::MacosxStrategy {}),
        _ => panic!("Unsupported system family"),
    }
}
