(module main)

(import std.fs (write_text_status read_text_result exists is_file remove_file_ok))

(import std.io (print_i32_zero))

(import std.math (clamp_i32 square_i32))

(import std.string (concat parse_i32_result))

(fn score_path () -> string
  "slovo-stdlib-composition-beta.txt")

(fn score_text () -> string
  (concat "4" "2"))

(fn seed_score_file () -> bool
  (= (write_text_status (score_path) (score_text)) 0))

(fn read_score_result () -> (result i32 i32)
  (if (seed_score_file)
    (match (read_text_result (score_path))
      ((ok text)
        (parse_i32_result text))
      ((err code)
        (err i32 i32 code)))
    (err i32 i32 1)))

(fn read_score_or_zero () -> i32
  (match (read_score_result)
    ((ok value)
      value)
    ((err code)
      0)))

(fn bounded_score () -> i32
  (clamp_i32 (read_score_or_zero) 0 10))

(fn computed_score () -> i32
  (square_i32 (bounded_score)))

(fn cleanup_score_file () -> bool
  (if (exists (score_path))
    (remove_file_ok (score_path))
    true))

(fn score_file_roundtrip_ok () -> bool
  (if (= (read_score_or_zero) 42)
    (if (exists (score_path))
      (if (is_file (score_path))
        (cleanup_score_file)
        false)
      false)
    false))

(fn main_score () -> i32
  (let value i32 (computed_score))
  (cleanup_score_file)
  value)

(fn main () -> i32
  (let value i32 (main_score))
  (print_i32_zero value))

(test "stdlib composition reads parses and cleans"
  (score_file_roundtrip_ok))

(test "stdlib composition clamps and squares"
  (if (= (computed_score) 100)
    (cleanup_score_file)
    false))

(test "stdlib composition main score"
  (= (main_score) 100))
