///|
/// Schema-directed parsing avoids a temporary JSON object tree on valid input.
/// Official scalar decoding and the legacy error path remain the reference.
priv struct HistoryScan {
  text : String
  strings : Map[String, String]
  mut pos : Int
  mut operations : Int
}

///|
fn HistoryScan::peek(self : HistoryScan) -> Int {
  if self.pos >= self.text.length() {
    -1
  } else {
    self.text.unsafe_get(self.pos).to_int()
  }
}

///|
fn HistoryScan::white(self : HistoryScan) -> Unit {
  while true {
    let c = self.peek()
    if c == 32 || c == 9 || c == 10 || c == 13 {
      self.pos += 1
    } else {
      break
    }
  }
}

///|
fn HistoryScan::expect(self : HistoryScan, code : Int) -> Unit raise {
  self.white()
  if self.peek() != code {
    fail("Unexpected history token")
  }
  self.pos += 1
}

///|
fn HistoryScan::slice(self : HistoryScan, start : Int) -> String raise {
  match self.text.get_view(start~, end=self.pos) {
    Some(view) => view.to_owned()
    None => fail("Invalid string boundary")
  }
}

///|
fn HistoryScan::string(self : HistoryScan) -> String raise {
  self.white()
  let start = self.pos
  if self.peek() != 34 {
    fail("Expected string")
  }
  self.pos += 1
  let mut plain_ascii = true
  while true {
    let c = self.peek()
    if c == -1 {
      break
    }
    self.pos += 1
    if c == 34 {
      if plain_ascii {
        return match self.text.get_view(start=start + 1, end=self.pos - 1) {
          Some(view) => view.to_owned()
          None => fail("Invalid ASCII boundary")
        }
      }
      let raw = self.slice(start)
      return match self.strings.get(raw) {
        Some(value) => value
        None => {
          let value = match @json.parse(raw) {
            String(s) => s
            _ => fail("Expected string")
          }
          self.strings[raw] = value
          value
        }
      }
    }
    if c < 32 {
      fail("Unescaped control character")
    }
    if c > 127 {
      plain_ascii = false
    }
    if c == 92 {
      plain_ascii = false
      if self.peek() == -1 {
        fail("Truncated escape")
      }
      self.pos += 1
    }
  }
  fail("Unclosed string")
}

///|
fn HistoryScan::identifier(self : HistoryScan) -> String raise {
  let value = self.string()
  if !valid_identifier(value) {
    fail("Invalid identifier")
  }
  value
}

///|
fn HistoryScan::field(self : HistoryScan, first : Bool) -> String? raise {
  self.white()
  if self.peek() == 125 {
    self.pos += 1
    return None
  }
  if !first {
    self.expect(44)
  }
  let key = self.string()
  self.expect(58)
  Some(key)
}

///|
fn HistoryScan::element(self : HistoryScan, first : Bool) -> Bool raise {
  self.white()
  if self.peek() == 93 {
    self.pos += 1
    return false
  }
  if !first {
    self.expect(44)
  }
  self.white()
  if self.peek() == 93 {
    fail("Trailing array comma")
  }
  true
}

///|
fn HistoryScan::number(self : HistoryScan) -> Double raise {
  self.white()
  let start = self.pos
  while self.peek() >= 0 &&
        self.peek() != 44 &&
        self.peek() != 125 &&
        self.peek() != 93 &&
        self.peek() != 32 &&
        self.peek() != 9 &&
        self.peek() != 10 &&
        self.peek() != 13 {
    self.pos += 1
  }
  if start == self.pos {
    fail("Missing number")
  }
  match @json.parse(self.slice(start)) {
    Number(n, ..) => n
    _ => fail("Expected number")
  }
}

///|
fn HistoryScan::timestamp(self : HistoryScan) -> Int64? raise {
  self.white()
  if self.peek() == 110 {
    for code in [110, 117, 108, 108] {
      if self.peek() != code {
        fail("Invalid null")
      }
      self.pos += 1
    }
    return None
  }
  let n = self.number()
  if n < 0.0 || n > 9007199254740991.0 || n.to_int64().to_double() != n {
    fail("Invalid timestamp")
  }
  Some(n.to_int64())
}

///|
fn mark_field(seen : Int, flag : Int) -> Int raise {
  if (seen & flag) != 0 {
    fail("Duplicate history field")
  }
  seen | flag
}

///|
fn HistoryScan::operation(self : HistoryScan) -> Operation raise {
  self.expect(123)
  let mut first = true
  let mut seen = 0
  let mut kind = Read
  let mut key = ""
  let mut version = ""
  while true {
    let name = match self.field(first) {
      Some(name) => name
      None => break
    }
    first = false
    match name {
      "type" => {
        seen = mark_field(seen, 1)
        kind = match self.string() {
          "read" => Read
          "write" => Write
          _ => fail("Invalid operation kind")
        }
      }
      "key" => {
        seen = mark_field(seen, 2)
        key = self.identifier()
      }
      "version" => {
        seen = mark_field(seen, 4)
        version = self.identifier()
      }
      _ => fail("Unknown operation field")
    }
  }
  if seen != 7 {
    fail("Missing operation field")
  }
  self.operations += 1
  if self.operations > 10000 {
    fail("Operation limit")
  }
  { kind, key, version, }
}

///|
fn HistoryScan::transaction(self : HistoryScan) -> Transaction raise {
  self.expect(123)
  let mut first = true
  let mut seen = 0
  let mut id = ""
  let mut status = Committed
  let ops : Array[Operation] = []
  let mut start : Int64? = None
  let mut end : Int64? = None
  while true {
    let name = match self.field(first) {
      Some(name) => name
      None => break
    }
    first = false
    match name {
      "id" => {
        seen = mark_field(seen, 1)
        id = self.identifier()
      }
      "status" => {
        seen = mark_field(seen, 2)
        status = match self.string() {
          "committed" => Committed
          "aborted" => Aborted
          "unknown" => Unknown
          _ => fail("Invalid status")
        }
      }
      "ops" => {
        seen = mark_field(seen, 4)
        self.expect(91)
        let mut first_op = true
        while self.element(first_op) {
          first_op = false
          ops.push(self.operation())
        }
      }
      "start" => {
        seen = mark_field(seen, 8)
        start = self.timestamp()
      }
      "end" => {
        seen = mark_field(seen, 16)
        end = self.timestamp()
      }
      _ => fail("Unknown transaction field")
    }
  }
  if (seen & 7) != 7 {
    fail("Missing transaction field")
  }
  { id, status, ops, start, end, }
}

///|
fn direct_history(text : String) -> Result[History, String] {
  if text.length() > 1048576 {
    return Err("History size limit")
  }
  try {
    let scan : HistoryScan = { text, strings: Map([]), pos: 0, operations: 0, }
    scan.expect(123)
    let mut first = true
    let mut seen = 0
    let mut model = Serializable
    let initial : Map[String, String] = Map([])
    let orders : Map[String, Array[String]] = Map([])
    let txs : Array[Transaction] = []
    while true {
      let name = match scan.field(first) {
        Some(name) => name
        None => break
      }
      first = false
      match name {
        "schemaVersion" => {
          seen = mark_field(seen, 1)
          if scan.number() != 1.0 {
            fail("Invalid schema")
          }
        }
        "name" => {
          seen = mark_field(seen, 2)
          let _ = scan.string()
        }
        "model" => {
          seen = mark_field(seen, 4)
          model = match scan.string() {
            "serializable" => Serializable
            "strict-serializable" => StrictSerializable
            _ => fail("Invalid model")
          }
        }
        "initial" => {
          seen = mark_field(seen, 8)
          scan.expect(123)
          let mut first_key = true
          while true {
            let key = match scan.field(first_key) {
              Some(key) => key
              None => break
            }
            first_key = false
            if !valid_identifier(key) || initial.contains(key) {
              fail("Invalid or duplicate initial key")
            }
            initial[key] = scan.identifier()
          }
        }
        "versionOrders" => {
          seen = mark_field(seen, 16)
          scan.expect(123)
          let mut first_key = true
          while true {
            let key = match scan.field(first_key) {
              Some(key) => key
              None => break
            }
            first_key = false
            if orders.contains(key) {
              fail("Duplicate version order")
            }
            scan.expect(91)
            let values : Array[String] = []
            let mut first_value = true
            while scan.element(first_value) {
              first_value = false
              values.push(scan.identifier())
            }
            orders[key] = values
          }
        }
        "transactions" => {
          seen = mark_field(seen, 32)
          scan.expect(91)
          let mut first_tx = true
          while scan.element(first_tx) {
            first_tx = false
            if txs.length() >= 512 {
              fail("Transaction limit")
            }
            txs.push(scan.transaction())
          }
        }
        _ => fail("Unknown history field")
      }
    }
    scan.white()
    if scan.pos != text.length() || (seen & 40) != 40 {
      fail("Missing or trailing history input")
    }
    Ok({ model, initial, version_orders: orders, transactions: txs, })
  } catch {
    e => Err(e.to_string())
  }
}

///|
/// Valid-input fast path; legacy decoding retains exact errors and uncommon cases.
pub fn parse_history_optimized(text : String) -> Result[History, String] {
  match direct_history(text) {
    Ok(h) => Ok(h)
    Err(_) => parse_history(text)
  }
}

///|
pub fn benchmark_parser_agreement(text : String) -> String {
  let fast = direct_history(text)
  let reference = parse_history(text)
  let agrees = match (fast, reference) {
    (Ok(a), Ok(b)) => a == b
    (Err(_), _) => true
    _ => false
  }
  let result : Json = {
    "agrees": agrees.to_json(),
    "fastPath": (fast is Ok(_)).to_json(),
    "referenceValid": (reference is Ok(_)).to_json(),
  }
  result.stringify()
}