use std::path::PathBuf;

pub trait Template {
    fn lib(project: &str) -> String;
    fn bin(project: &str) -> String;

    fn create(project: &str, lib: bool) -> String {
        if lib {
            Self::lib(project)
        } else {
            Self::bin(project)
        }
    }
}

pub struct Dsa;
pub struct Dsc;

impl Template for Dsa {
    fn lib(project: &str) -> String {
        format!(
            r#"//
lib.dsa
// usage:
//
// include {project} "<relative path>"
//
// usage for {project}_main:
// push (arg1)
// push (arg0)
// call {project}::{project}_main
// pop (arg0)
// pop (arg1)

// Example data declarations
// dw example_data: 0x0000

// Main function template
{project}_main:
    // the correct way to start a function as defined by the calling convention
    push bpr
    mov spr, bpr

    // explanation of how to access args
    ldw bpr, rg0, 8  // arg 0
    ldw bpr, rg0, 12 // arg 1

    // your code goes here
    // Example: load example_data into rg1
    // ldw example_data, rg1

    // the correct way to end a function as defined by the calling convention
    mov bpr, spr
    pop bpr
    return
"#,
        )
    }

    fn bin(project: &str) -> String {
        format!(
            r#"
// GENERATED BY DSX-BUILD
// Generated at: {timestamp}
// Project name: {project}

// Imports
include print: "./lib/print.dsa"

// Globals & Reserved Memory
dw stack: 0x10000
db message: "Process Exited with code:"

// Entry Point
_init:
    ldw stack, bpr
    mov bpr, spr
    push zero
    call main
    call print::print_newline
    lwi message, rg0
    push rg0
    call print::print
    pop zero
    call print::print_hex_word
    pop zero
    hlt

main:
    push bpr
    mov spr, bpr

    // Your code goes here

    // Return zero
    stw zero, bpr, 8

    mov bpr, spr
    pop bpr
    return"#,
            timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S")
        )
    }
}

impl Template for Dsc {
    fn lib(project: &str) -> String {
        format!(
            r#"
// GENERATED BY DSX-BUILD
// Generated at: {timestamp}
// Project name: {project}

// Imports
include print: "./lib/print.dsa";

// Main Function
fn {project}_main() -> u32 {{
    return 0;
}}"#,
            timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S")
        )
    }

    fn bin(project: &str) -> String {
        format!(
            r#"
// GENERATED BY DSX-BUILD
// Generated at: {timestamp}
// Project name: {project}

// Imports
include print: "./lib/print.dsa";

// Main Function
fn main() -> u32 {{
    return 0;
}}"#,
            timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S")
        )
    }
}
