
use std::fs::File;

use crate::{
    cpu::CPU,
    instruction_set::instruction_data::InstructionData,
    memory_manager::{
        MemoryStorable,
        type_traits::{FromFloat, UpcastDestTraits, UpcastSlice},
    },
    tracing::Trace,
    utility::{add_offset_r1, add_offset_rd},
};
use std::io::Write;

#[cfg(not(feature = "tracing"))]
impl Trace {
    ///////////////////////////////////////////////////////////////
    /////////////////Scalar/register Instructions//////////////////
    ///////////////////////////////////////////////////////////////

    pub fn pre_sldi(&mut self, cores: &mut CPU, data: InstructionData) {

    }

    pub fn post_sldi(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_sld(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_sld(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_sadd(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_sadd(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_ssub(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_ssub(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_smul(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_smul(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_saddi(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_saddi(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_smuli(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_smuli(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    /////////////////////////////////////////////////////////////////
    ///////////////////Matrix/vector Instructions////////////////////
    /////////////////////////////////////////////////////////////////

    pub fn pre_setbw(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_setbw(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_mvm<F, M, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T> + UpcastSlice<M>,
        [M]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        M: UpcastDestTraits<M> + MemoryStorable + FromFloat,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
        self.mvm_impl::<F,M,T>(cores, data, "Pre");
    }

    pub fn post_mvm<F, M, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T> + UpcastSlice<M>,
        [M]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        M: UpcastDestTraits<M> + MemoryStorable + FromFloat,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
        self.mvm_impl::<F,M,T>(cores, data, "Post");
    }

    pub fn mvm_impl<F, M, T>(&mut self, cores: &mut CPU, data: InstructionData, prefix : &'static str)
    where
        [F]: UpcastSlice<T> + UpcastSlice<M>,
        [M]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        M: UpcastDestTraits<M> + MemoryStorable + FromFloat,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn pre_vvadd<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn post_vvadd<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn pre_vvsub<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn post_vvsub<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn pre_vvmul<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn post_vvmul<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn pre_vvdmul<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn post_vvdmul<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn pre_vvmax<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn post_vvmax<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn pre_vavg<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn post_vavg<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable,
    {
    }

    pub fn pre_vrelu<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable + From<f32>,
    {
    }

    pub fn post_vrelu<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable + From<f32>,
    {
    }

    pub fn pre_vtanh<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable + From<f32>,
    {
    }

    pub fn post_vtanh<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable + From<f32>,
    {
    }

    pub fn pre_vsigm<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable + From<f32>,
    {
    }

    pub fn post_vsigm<F, T>(&mut self, cores: &mut CPU, data: InstructionData)
    where
        [F]: UpcastSlice<T>,
        T: UpcastDestTraits<T> + MemoryStorable,
        F: UpcastDestTraits<F> + MemoryStorable + From<f32>,
    {
    }

    /////////////////////////////////////////////////////////////////
    /////Communication/synchronization Instructions/////////////////
    /////////////////////////////////////////////////////////////////
    pub fn pre_ld(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_ld(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_st(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_st(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_lldi(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_lldi(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_lmv(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_lmv(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_send(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_send(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn pre_recv(&mut self, cores: &mut CPU, data: InstructionData) {
    }

    pub fn post_recv(&mut self, cores: &mut CPU, data: InstructionData) {
    }
}
