(module main)

(fn fixture_path () -> string
  "slovo-exp10-host-io-result.txt")

(fn ok_text ((value string)) -> (result string i32)
  (ok string i32 value))

(fn err_text ((code i32)) -> (result string i32)
  (err string i32 code))

(fn result_text_or_error ((value (result string i32))) -> string
  (match value
    ((ok payload)
      payload)
    ((err code)
      (std.io.print_i32 code)
      "error")))

(fn result_text_len_or_code ((value (result string i32))) -> i32
  (match value
    ((ok payload)
      (std.string.len payload))
    ((err code)
      code)))

(fn write_fixture_result () -> (result i32 i32)
  (std.fs.write_text_result (fixture_path) "exp10 host io"))

(fn read_fixture_result () -> (result string i32)
  (std.fs.write_text_result (fixture_path) "exp10 host io")
  (std.fs.read_text_result (fixture_path)))

(fn missing_env_result () -> (result string i32)
  (std.env.get_result "SLOVO_EXP10_MISSING_ENV"))

(fn first_arg_ok_score () -> i32
  (if (< 0 (std.process.argc))
    (if (is_ok (std.process.arg_result 0))
      1
      0)
    0))

(fn read_unwrapped_text () -> string
  (unwrap_ok (read_fixture_result)))

(fn missing_env_code () -> i32
  (unwrap_err (missing_env_result)))

(test "string result constructor ok"
  (= (result_text_or_error (ok_text "constructed")) "constructed"))

(test "string result constructor err"
  (= (result_text_len_or_code (err_text 1)) 1))

(test "missing env returns err 1"
  (= (missing_env_code) 1))

(test "arg result is ok when argc is positive"
  (= (first_arg_ok_score) (if (< 0 (std.process.argc))
    1
    0)))

(test "write text result returns ok zero"
  (= (unwrap_ok (write_fixture_result)) 0))

(test "read text result returns written text"
  (= (read_unwrapped_text) "exp10 host io"))

(test "read text result match observes string payload"
  (= (result_text_len_or_code (read_fixture_result)) 13))

(fn main () -> i32
  (std.io.eprint "exp-10 host io result")
  (if (is_ok (write_fixture_result))
    (unwrap_ok (write_fixture_result))
    1))
