use serde::{Deserialize, Serialize};

// =======================================================
// =======================================================
// TRACE EVENT BUILDER
// =======================================================
// =======================================================

pub struct TraceEventBuilder {
    name: String,
    cat: String,
    ph: String,
    ts: u64,
    dur: u64,
    pid: u32,
    tid: u64,
    args: Option<serde_json::Value>,
}

impl TraceEventBuilder {
    pub fn with_name(mut self, name: String) -> Self {
        self.name = name;
        self
    }

    pub fn with_cat(mut self, cat: String) -> Self {
        self.cat = cat;
        self
    }

    pub fn with_ph(mut self, ph: String) -> Self {
        self.ph = ph;
        self
    }

    pub fn with_ts(mut self, ts: u64) -> Self {
        self.ts = ts;
        self
    }

    pub fn with_dur(mut self, dur: u64) -> Self {
        self.dur = dur;
        self
    }

    pub fn with_pid(mut self, pid: u32) -> Self {
        self.pid = pid;
        self
    }

    pub fn with_tid(mut self, tid: u64) -> Self {
        self.tid = tid;
        self
    }

    pub fn args(mut self, args: Option<serde_json::Value>) -> Self {
        self.args = args;
        self
    }

    pub fn build(self) -> TraceEvent {
        TraceEvent {
            name: self.name,
            cat: self.cat,
            ph: self.ph,
            ts: self.ts,
            dur: self.dur,
            pid: self.pid,
            tid: self.tid,
            args: self.args,
        }
    }
}

impl Default for TraceEventBuilder {
    fn default() -> Self {
        Self {
            name: "Unnamed".into(),
            cat: "function".into(),
            ph: "X".into(),
            ts: 0,
            dur: 0,
            pid: 0,
            tid: 0,
            args: None,
        }
    }
}

// =======================================================
// =======================================================
// TRACE EVENT
// =======================================================
// =======================================================

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TraceEvent {
    pub name: String,
    pub cat: String,
    pub ph: String,
    pub ts: u64,
    pub dur: u64,
    pub pid: u32,
    pub tid: u64,
    pub args: Option<serde_json::Value>,
}

impl TraceEvent {
    pub fn complete(name: impl Into<String>, ts: u64, dur: u64, tid: u64) -> Self {
        Self {
            name: name.into(),
            cat: "function".into(),
            ph: "X".into(),
            ts,
            dur,
            pid: 0,
            tid,
            args: None,
        }
    }
}
