module default {
  function is_winner_me(winner: str) -> bool
    using (winner = "me");

  function gameboard_url(id: uuid) -> str
    using ("https://play.battlesnake.com/game/" ++ <str>id);

  type GameBoard {
    overloaded required id: uuid {
      readonly := true;
      constraint exclusive;
    }
    url := gameboard_url(.id);

    required created_at: datetime {
      readonly := true;
    }
    required turns: int32 {
      readonly := true;
    }
    required map: str {
      readonly := true;
      default := "standard";
    }
    required single type: GameType {
      readonly := true;
      on source delete delete target if orphan;
    }
    required single ruleset: Ruleset {
      readonly := true;
      on source delete delete target if orphan;
    }
    required winner: str {
      readonly := true;
    }
    required multi moves: Moves {
      readonly := true;
      on source delete delete target;
    }
    required single snake: Snake {
      readonly := true;
      on source delete delete target if orphan;
    }

    is_winner_me := is_winner_me(.winner)
  }

  type GameType {
    required name: str {
      readonly := true;
    }
    required is_ladder: bool {
      readonly := true;
    }
    constraint exclusive on ( (.name, .is_ladder) );
  }

  type Ruleset {
    required name: str {
      readonly := true;
    }
    required version: str {
      readonly := true;
    }
    required settings: json {
      readonly := true;
    }
    constraint exclusive on ( (.name, .version, .settings) );
  }

  type Snake {
    required type: str {
      readonly := true;
    }
    constraint exclusive on ( .type );
  }

  type Moves {
    required turn: int32 {
      readonly := true;
    }
    required snake_move: str {
      readonly := true;
    }
    required game_board: json {
      readonly := true;
    }
    calculations: array<json> {
      readonly := true;
    }
  }

}
