#include <fmt/core.h>
#include <string>
#include <vector>
#include <string_view>
#include <charconv>
#include "dbc.hpp"

using namespace fmt;

%%{
  machine foo;

  action tstart {
    start = fpc;
  }

  action number {
    auto [ptr, ec] = std::from_chars(start, fpc, value);
    dbc::check(ec == std::errc(), "error in number parsing");
    println("NUMBER {}", value);
  }

  action color256 {
   println("256 color");
  }

  action color24b {
    println("true color");
  }

  action colorSingle {
    println("single color");
  }

  action colorBasic {
    println("basic color");
  }

  action bg {
    println("BG");
  }

  action fg {
    println("FG");
  }

  start = 0x1B "[";
  fg = "38;" %fg;
  bg = "48;" %bg;
  num = digit+ >tstart %number;
  color256 = "5;" num ";" num;
  color24b = "2;" num ";" num ";" num;
  basic = num ";" num;
  single = num;

  main := (
      start %{ println("START"); }
      (
        (fg|bg) color256 %color256 |
        (fg|bg) color24b %color24b |
        single %colorSingle |
        basic %colorBasic
      )**
      "m" %{ println("END"); }
    )**;
}%%

%% write data;

void parse_ansi(std::string_view &codes) {
  const char *start = NULL;
  int cs = 0;
  size_t value = 0;
  const char *p = codes.data();
  const char *pe = p + codes.size();
  const char *eof = pe;

  %% write init;
  %% write exec;
}

int main() {
  // possibly put alphtype unsigned int?
  std::vector<std::string_view> tests = {
    "\x1B[38;5;78;98m",
    "\x1B[48;5;78;98m",
    "\x1B[38;2;36;46;23m",
    "\x1B[48;2;36;46;23m",
    "\x1B[36;46m",
    "\x1B[36m",
  };

  for(auto test : tests) {
    println("--- PARSING");
    parse_ansi(test);
  }

  return 0;
}
