use chrono::{DateTime, Utc};
use rstest::rstest;
use serde::Deserialize;
use serde_xml_rs::from_reader;
use std::fs::File;

#[derive(Debug, PartialEq, Deserialize)]
#[serde(rename = "h:execution")]
struct Execution {
    infrastructure: Option<Infrastructure>,
    #[serde(rename = "h:root")]
    roots: Vec<Node>,
}

#[derive(Debug, PartialEq, Deserialize)]
#[serde(rename = "e:events")]
struct Events {
    infrastructure: Option<Infrastructure>,
    #[serde(rename = "#content", default)]
    events: Vec<Event>,
}

#[derive(Debug, PartialEq, Deserialize)]
enum Event {
    #[serde(rename = "e:started")]
    Started {
        #[serde(rename = "@id")]
        id: String,
        #[serde(rename = "@time")]
        time: DateTime<Utc>,
        #[serde(rename = "@parentId")]
        parent_id: Option<String>,
    },
    #[serde(rename = "e:reported")]
    Reported {
        #[serde(rename = "@id")]
        id: String,
        #[serde(rename = "@time")]
        time: DateTime<Utc>,
    },
    #[serde(rename = "e:finished")]
    Finished {
        #[serde(rename = "@id")]
        id: String,
        #[serde(rename = "@time")]
        time: DateTime<Utc>,
        result: Result,
    },
}

#[derive(Debug, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Infrastructure {
    host_name: Option<String>,
    user_name: Option<String>,
    operating_system: Option<String>,
    cpu_cores: Option<usize>,
}

#[derive(Debug, PartialEq, Deserialize)]
struct Node {
    #[serde(rename = "@duration")]
    duration: String,
    #[serde(rename = "@name")]
    name: String,
    #[serde(rename = "@start")]
    start: DateTime<Utc>,
    #[serde(rename = "h:child", default)]
    children: Vec<Node>,
    result: Option<Result>,
}

#[derive(Debug, PartialEq, Deserialize)]
struct Result {
    #[serde(rename = "@status")]
    status: Status,
}

#[derive(Debug, PartialEq, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
enum Status {
    Successful,
    Skipped,
    Aborted,
    Failed,
    Errored,
}

#[rstest]
#[test_log::test]
fn given_test_execution_when_deserialize() {
    let file = File::open("tests/opentest/test-execution.xml").unwrap();
    let _value: Execution = from_reader(file).unwrap();
}

#[rstest]
#[test_log::test]
fn given_test_events_when_deserialize() {
    let file = File::open("tests/opentest/test-events.xml").unwrap();
    let _value: Events = from_reader(file).unwrap();
}
