/**
 * Assert that structs may be joined with sugary array types to allow for
 * indexing into a struct.
 *
 *
 */
import { Assert } from '../src/walt/tests.walt';
import { assert : Assert, memory : Memory } from 'env';

export const INTROSPECT_PRETTY_PRINT : i32 = 0;

let OFFSET : i32;

type BaseString = { byteLength: i32 };
type DataAccess = { spacer: i32, &data: i32[] };
type String = BaseString | DataAccess | i32[];


function assert_unions(string : String) {
  string.spacer = 4;

  assert("setting values of union fields", string.spacer, string.byteLength);
  // Test union types. Assign the value of "fooz" to the first index in the
  // i32[] array type version of string
  string[1] = 'f' | ('o' << 8) | ('o' << 16) | ('z' << 24);

  // Direct addressing test. Read back values written via direct addressing
  // and built-in native functions
  assert("char offset of string - f", i32.load8_u(string.data), 'f');
  assert("char offset of string - o", i32.load8_u(string.data + 1), 'o');
  assert("char offset of string - o", i32.load8_u(string.data + 2), 'o');
  assert("char offset of string - z", i32.load8_u(string.data + 3), 'z');

  // NOTE: using the offset (1024) here to sanity check the "start" logic
  assert("address sanity check - f", i32.load8_u(1024 + 4), 'f');
  assert("address sanity check - o", i32.load8_u(1024 + 4 + 1), 'o');
  assert("address sanity check - o", i32.load8_u(1024 + 4 + 2), 'o');
  assert("address sanity check - z", i32.load8_u(1024 + 4 + 3), 'z');
}

function array_struct_unions() {
  const base : BaseString = OFFSET;
  assert_unions(base);
  const string : String = base;
  assert_unions(string);
}

export function run() {
  array_struct_unions();
}

function start() {
  OFFSET = 1024;
}
