#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

void ucalc_call IsValidEmail(uCalcBase::Callback cb) {
   auto email = cb.ArgStr(1);
   auto uc = cb.uCalc();
   // Simple validation: check for '@' and '.'
   auto isValid = uc.EvalStr("Contains('" + email + "', '@') And Contains('" + email + "', '@')");
   if (isValid == "true") {
      cb.ReturnBool(true);
   } else {
      cb.ReturnBool(false);
   }
}

int main() {
   uCalc uc;
   // 1. Define the custom validation function in the uCalc engine
   uc.DefineFunction("IsValidEmail(email As String) As Bool", IsValidEmail);

   // 2. Create and configure the transformer
   {
      uCalc::Transformer t(uc);
      t.Owned(); // Causes t to be released when it goes out of scope
      // 3. Define the sanitization and validation rules
      t.FromTo("user = {val};", "User: {val},");
      t.FromTo("age = {val};", "Age: {val},");
      t.FromTo("status = {val}", "Status: {@Eval: UCase(val)}"); // Last rule, no trailing comma

      // The email rule uses the custom function for validation
      t.FromTo("email = {val};",
      "Email: {val} {@Eval: IIf(IsValidEmail(val), '(Valid)', '(INVALID)')},");

      // 4. Define the messy input strings
      auto input1 = "user= Alice  ; age= 30 ; email= alice@ucalc.com ; status=active";
      auto input2 = "user= Bob; age= 45; email= bob-at-ucalc ; status=inactive";

      // 5. Run the transformations
      cout << t.Transform(input1) << endl;
      cout << t.Transform(input2) << endl;
   };
}