#[cfg(feature = "publisher")]
use chrono::NaiveDate;

#[cfg(feature = "publisher")]
use tavern::{Adventurer, Legend, Lore, Story, Tale, Tavern};

#[cfg(feature = "publisher")]
use tavern::Database;



/// This will generate a tavern that we can create a Toml file from.
#[cfg(feature = "publisher")]
fn generate_tavern() -> Tavern
{
   let legend: Legend = Legend
   {
      profile: String::from("https://cybermages.tech/about/myrddin"),
      image: String::from("https://cybermages.tech/about/myrddin/pic"),
      blurb: String::from("I love code!")
   };

   let author: Adventurer = Adventurer
   {
      name: String::from("Jason Smith"),
      handle: String::from("myrddin"),
      legend: legend
   };

   let lore: Lore = Lore
   {
      title: String::from("Test post"),
      slug: String::from("test_post"),
      author: author.handle.clone(),
      summary: String::from("The Moon is made of cheese!"),
      tags: vec![String::from("Space"), String::from("Cheese")],
      publish_date:
         NaiveDate::from_ymd_opt(2025, 12, 25).unwrap()
                                              .and_hms_opt(13, 10, 41)
                                              .unwrap()
   };

   let tale: Tale = Tale
   {
      lore: lore,
      story: Story::Html("#Test Post\nThis is a test post.\n\n##Subsection\nMini post.\n* Test 1\n* Test 2\n* Test 3".to_string())
   };

   let lore2: Lore = Lore
   {
      title: String::from("Test Tale"),
      slug: String::from("test_tale"),
      author: author.handle.clone(),
      summary: String::from("The Moon is made of rocks!"),
      tags: vec![String::from("Space"), String::from("Rocks")],
      publish_date:
         NaiveDate::from_ymd_opt(2025, 12, 25).unwrap()
                                              .and_hms_opt(13, 10, 41)
                                              .unwrap()
   };

   let tale2: Tale = Tale
   {
      lore: lore2,
      story: Story::Html("#Test Tale\nThis is a test tale.\n\n##Subsection\nMini tale.\n* Test 1\n* Test 2\n* Test 3".to_string())
   };

   Tavern { title: String::from("Runes & Ramblings"),
            description: String::from("Join software engineer Jason Smith \
                                       on his Rust programming journey. \
                                       Explore program design, tech \
                                       stacks, and more on this blog from \
                                       CybeMages, LLC."),
            tales: vec![tale, tale2],
            authors: vec![author] }
}


#[cfg(feature = "publisher")]
fn create_temp_file<P>(filename: P) -> std::path::PathBuf
   where P: AsRef<std::path::Path>
{
   let mut path = std::env::temp_dir();
   path.push(filename);

   path
}

#[cfg(feature = "publisher")]
fn cleanup_temp_file<P>(path: P)
   where P: AsRef<std::path::Path>
{
   match path.as_ref().try_exists()
   {
      Ok(exists) =>
      {
         if exists
         {
            let _ = std::fs::remove_file(path);
         }
      }

      Err(e) =>
      {
         eprintln!("{}", e);
      }
   }
}

#[cfg(feature = "publisher")]
fn write_to_file<P>(tavern: Tavern, config_file: P) -> Result<(), Box<dyn std::error::Error>>
   where P: AsRef<std::path::Path>
{
   let toml_string = toml::to_string_pretty(&tavern)?;

   std::fs::write(&config_file, &toml_string)?;

   Ok(())
}

#[cfg(feature = "publisher")]
fn read_from_file<P>(config_file: P) -> Tavern
   where P: AsRef<std::path::Path>
{
   // Read the previously written TOML file
   let toml_data =
      std::fs::read_to_string(&config_file).expect("Failed to read TOML file");

   // Deserialize it
   toml::from_str(&toml_data).expect("Failed to parse TOML")
}


#[cfg(feature = "publisher")]
async fn create_database() -> Result<(), Box<dyn std::error::Error>>
{
   // First we need to generate a TOML file to work with.
   let config_path = create_temp_file("tavern.toml");
   cleanup_temp_file(&config_path);

   write_to_file(generate_tavern(), &config_path)?;

   // This part would be the entry point of your CI/CD script
   // It would load your data and then save it to the database

   // Create a Tavern object
   let tavern = read_from_file(&config_path);

   // Open the database and save the Tavern content
   let db_path = create_temp_file("tavern.db");
   cleanup_temp_file(&db_path);

   let db = Database::open(db_path).await?;
   db.insert_tavern(&tavern).await?;

   Ok(())
}

#[cfg(feature = "publisher")]
#[tokio::main]
pub async fn main()
{
   match create_database().await
   {
      Ok(_) => {}
      Err(e) => { eprintln!("Error: {}", e); }
   }
}


#[cfg(not(feature = "publisher"))]
#[tokio::main]
pub async fn main()
{
}
