// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

///|
/// Parsed post table (subset).
pub struct PostTable {
  version : Int
  italic_angle : Int
  underline_position : Int
  underline_thickness : Int
  is_fixed_pitch : Int
  min_mem_type42 : Int
  max_mem_type42 : Int
  min_mem_type1 : Int
  max_mem_type1 : Int
  glyph_name_indices : Array[Int]?
  custom_names : Array[Bytes]?
} derive(Show, ToJson)

///|
fn read_i32(data : BytesView, offset : Int) -> Result[Int, SfntError] {
  match read_u32(data, offset) {
    Err(err) => Err(err)
    Ok(value) => Ok(value.reinterpret_as_int())
  }
}

///|
fn parse_post_names(
  data : BytesView,
  offset : Int,
  num_glyphs : Int,
) -> Result[(Array[Int], Array[Bytes]), SfntError] {
  if num_glyphs < 0 {
    return Err(InvalidFormat)
  }
  let indices : Array[Int] = []
  let mut cursor = offset
  let end = data.length()
  for _ in 0.. return Err(err)
      Ok(value) => indices.push(value)
    }
    cursor = cursor + 2
  }
  let custom_names : Array[Bytes] = []
  while cursor < end {
    let length = data[cursor].to_uint().reinterpret_as_int()
    cursor = cursor + 1
    if length < 0 {
      return Err(InvalidFormat)
    }
    let next = cursor + length
    if next > end {
      return Err(UnexpectedEof)
    }
    let bytes : Array[Byte] = []
    for i in cursor.. Result[PostTable, SfntError] {
  let version = read_u32_int(data, 0)
  let italic_angle = read_i32(data, 4)
  let underline_position = read_i16(data, 8)
  let underline_thickness = read_i16(data, 10)
  let is_fixed_pitch = read_u32_int(data, 12)
  let min_mem_type42 = read_u32_int(data, 16)
  let max_mem_type42 = read_u32_int(data, 20)
  let min_mem_type1 = read_u32_int(data, 24)
  let max_mem_type1 = read_u32_int(data, 28)
  match (
    version,
    italic_angle,
    underline_position,
    underline_thickness,
    is_fixed_pitch,
    min_mem_type42,
    max_mem_type42,
    min_mem_type1,
    max_mem_type1,
  ) {
    (Err(err), _, _, _, _, _, _, _, _) => Err(err)
    (_, Err(err), _, _, _, _, _, _, _) => Err(err)
    (_, _, Err(err), _, _, _, _, _, _) => Err(err)
    (_, _, _, Err(err), _, _, _, _, _) => Err(err)
    (_, _, _, _, Err(err), _, _, _, _) => Err(err)
    (_, _, _, _, _, Err(err), _, _, _) => Err(err)
    (_, _, _, _, _, _, Err(err), _, _) => Err(err)
    (_, _, _, _, _, _, _, Err(err), _) => Err(err)
    (_, _, _, _, _, _, _, _, Err(err)) => Err(err)
    (
      Ok(version),
      Ok(italic_angle),
      Ok(underline_position),
      Ok(underline_thickness),
      Ok(is_fixed_pitch),
      Ok(min_mem_type42),
      Ok(max_mem_type42),
      Ok(min_mem_type1),
      Ok(max_mem_type1),
    ) => {
      let mut glyph_name_indices : Array[Int]? = None
      let mut custom_names : Array[Bytes]? = None
      if version == 0x00020000 {
        let num_glyphs = read_u16_int(data, 32)
        match num_glyphs {
          Err(err) => return Err(err)
          Ok(num_glyphs) => {
            let names = match parse_post_names(data, 34, num_glyphs) {
              Err(err) => return Err(err)
              Ok(value) => value
            }
            let (indices, names) = names
            glyph_name_indices = Some(indices)
            custom_names = Some(names)
          }
        }
      }
      Ok(PostTable::{
        version,
        italic_angle,
        underline_position,
        underline_thickness,
        is_fixed_pitch,
        min_mem_type42,
        max_mem_type42,
        min_mem_type1,
        max_mem_type1,
        glyph_name_indices,
        custom_names,
      })
    }
  }
}