import { exec } from 'child_process';

const nodemailer = require('nodemailer');

exec('iching divine', (error, stdout, stderr) => {

    console.log(`Begin`);

    if (error) {
        console.error(`Error: ${error.message}`);
        return;
    }

    if (stderr) {
        console.error(`Stderr: ${stderr}`);
        return;
    }

    console.log(`Send E-Mail`);

    sendEmail(stdout);
    sleep();
});

// Create Transporter
const transporter = nodemailer.createTransport({
    host: "mailhog.mailhog.svc.cluster.local", // MailHog ClusterIP
    port: 1025,         // Standard-MailHog SMTP-Port
    secure: false       // MailHog needs no encryption
});
  
// Send E-Mail
async function sendEmail(content: string) {
  try {
    const info = await transporter.sendMail({
      from: '"The Oracle" <the.oracle@holy.mountain>',
      to: "Christopher.Hase@telekom.com;test@mailhog.local",
      subject: "Your Horoscope Is Ready",
      text: content,
      html: html(content)
    });

    console.log("E-Mail sent: ", info.messageId);
  } catch (error) {
    console.error("Error Sending E-Mail:", error);
  }
}

//Sleep. To avoid issue in pod: Completed -> Terminated -> CrashLoopBackOff 
async function sleep() {
  console.log("Go to sleep: ", new Date().toISOString());

    // sleep 1h (3600000 ms)
    setTimeout(() => {
      sleep(); // recursion after 1h
  }, 3600000);  
}

//node structure for the Parse Tree (it's a degenerated tree with one or zero children per node)
interface Node {
  type: "Root" | "Hexagram" | "Judgement" | "Images" | "ChangingLines" ;
  child?: Node;
  value?: string;
}

//generate 1) Parse Tree and 2) HTML
function html(inputText: string): string {
  const parseTree = parse(inputText);
  const htmlOutput = render(parseTree);

  return htmlOutput;
}

//generate the Parse Tree
function parse(input: string): Node {

  console.log("Parse input text");

  const root: Node = { type: "Root"};
  var currentNode: Node = root;

  const lines = input.split("\n");

  for (const line of lines) {
    if (line.startsWith("Hexagram")) {
      const hexagram: Node = { type: "Hexagram"};
      currentNode.child = hexagram;
      currentNode = hexagram;
      currentNode.value = "<h1>" + line + "</h1>";
    } else if (line.startsWith("Judgement")) {
      const judgement: Node = { type: "Judgement"};
      currentNode.child = judgement;
      currentNode = judgement;
      currentNode.value = "<h3>" + line + "</h3>";
    } else if (line.startsWith("Images")) {
      const images: Node = { type: "Images"};
      currentNode.child = images;
      currentNode = images;
      currentNode.value = "<h3>" + line + "</h3>";
    } else if (line.startsWith("~") && currentNode.type != "ChangingLines") {
      const changingLines: Node = { type: "ChangingLines"};
      currentNode.child = changingLines;
      currentNode = changingLines;
      currentNode.value = line + "<br>";
    } else {
      currentNode.value = currentNode.value + line + "<br>";
    }
  }

  return root;
}

//generate HTML from Parse Tree
function render(node: Node): string {

  if (node == undefined) {
    console.log("...finished...")

    return "";
  }

  console.log("Render node" + node.type);

  var outputHTML: string = "";

  switch (node.type) {
    case "Root":
      return render(node.child!);
    case "Hexagram":
      //node.value = node.value?.replace("</h1>", "</h1><h3>"); 
      node.value = node.value?.replace("</h1>", "</h1><div style=\"border: 1px solid gray; border-radius: 15px; padding: 15px; width: 400px; text-align: center; box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.2);\"><h2>"); 
      node.value = node.value?.replace("<br>", "  -  ");
      //outputHTML = "<p>" + node.value + "</h3></p>";
      outputHTML = "<p>" + node.value + "</h2></div></p>";
      outputHTML = outputHTML + render(node.child!);

      return outputHTML;

    case "ChangingLines" :
      outputHTML = "<p style=\"color: gray;\">" + node.value + "</p>";
      outputHTML = outputHTML + render(node.child!);

      return outputHTML;

    default:
      outputHTML = "<p>" + node.value + "</p>";
      outputHTML = outputHTML + render(node.child!);

      return outputHTML;

  }
}
  