{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:bgi:schema:solution:1",
  "title": "bgi saved solution v1",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "bgi_version",
    "algorithm",
    "project_construction_sha256",
    "candidate_id",
    "construction_sha256",
    "original_manufacturing_sha256",
    "search",
    "layout"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "bgi_version": {
      "type": "string",
      "minLength": 1
    },
    "algorithm": {
      "enum": [
        "compact-guillotine-v10",
        "compact-guillotine-v9",
        "compact-guillotine-v8",
        "compact-guillotine-v7",
        "compact-guillotine-v6",
        "compact-guillotine-v5",
        "compact-guillotine-v4",
        "compact-guillotine-v3",
        "compact-guillotine-v2",
        "axis-strips-v1"
      ]
    },
    "project_construction_sha256": {
      "$ref": "#/$defs/sha256"
    },
    "candidate_id": {
      "type": "string",
      "pattern": "^candidate-[0-9a-f]{12}$"
    },
    "construction_sha256": {
      "$ref": "#/$defs/sha256"
    },
    "original_manufacturing_sha256": {
      "$ref": "#/$defs/sha256"
    },
    "original_material": {
      "type": "object"
    },
    "original_manufacturing": {
      "type": [
        "object",
        "null"
      ]
    },
    "search": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "budget",
        "top_k"
      ],
      "properties": {
        "budget": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100000
        },
        "top_k": {
          "type": "integer",
          "minimum": 1,
          "maximum": 10
        }
      }
    },
    "evaluation": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "status",
        "physical_fit_verified",
        "metrics"
      ],
      "properties": {
        "status": {
          "const": "passed_supported_digital_checks"
        },
        "physical_fit_verified": {
          "const": false
        },
        "metrics": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "outer_mm",
            "panel_count",
            "nominal_area_tick2",
            "cut_length_ticks"
          ],
          "properties": {
            "outer_mm": {
              "$ref": "#/$defs/size3"
            },
            "occupied_height_mm": {
              "type": "number",
              "minimum": 0
            },
            "panel_count": {
              "type": "integer",
              "minimum": 0
            },
            "nominal_area_tick2": {
              "type": "integer",
              "minimum": 0
            },
            "cut_length_ticks": {
              "type": "integer",
              "minimum": 0
            }
          }
        }
      }
    },
    "layout": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "assembly",
        "origin_mm",
        "axis",
        "choices",
        "interior"
      ],
      "properties": {
        "assembly": {
          "$ref": "#/$defs/id"
        },
        "optional_groups": {
          "type": "array",
          "maxItems": 4,
          "uniqueItems": true,
          "items": {
            "$ref": "#/$defs/id"
          }
        },
        "origin_mm": {
          "$ref": "#/$defs/point"
        },
        "shape": {
          "oneOf": [
            {
              "enum": [
                "strip",
                "t-first",
                "t-second",
                "cross",
                "grid-2x3",
                "grid-2x4",
                "grid-2x5",
                "grid-2x6",
                "grid-2x7",
                "grid-2x8",
                "grid-2x9",
                "grid-2x10",
                "grid-3x3",
                "grid-3x4",
                "grid-3x5",
                "grid-3x6",
                "grid-4x4",
                "grid-4x5"
              ]
            },
            {
              "type": "string",
              "pattern": "^hybrid-[xy]-(strip|t-first|t-second|cross|grid-[2-4]x[2-9]|grid-2x10)(__[xy]-(strip|t-first|t-second|cross|grid-[2-4]x[2-9]|grid-2x10)){0,19}$"
            }
          ]
        },
        "axis": {
          "enum": [
            "x",
            "y"
          ]
        },
        "choices": {
          "type": "array",
          "minItems": 1,
          "maxItems": 20,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "requirement",
              "orientation"
            ],
            "properties": {
              "requirement": {
                "$ref": "#/$defs/id"
              },
              "orientation": {
                "oneOf": [
                  {
                    "enum": [
                      "xy",
                      "yx",
                      "flat_xy",
                      "flat_yx",
                      "upright_x",
                      "upright_y",
                      "xyz",
                      "xzy",
                      "yxz",
                      "yzx",
                      "zxy",
                      "zyx",
                      "row_x",
                      "row_y",
                      "positions_xy",
                      "stack_z"
                    ]
                  },
                  {
                    "type": "string",
                    "maxLength": 80,
                    "pattern": "^footprint-[1-9][0-9]*-height-[1-9][0-9]*$"
                  }
                ]
              }
            }
          }
        },
        "interior": {
          "$ref": "#/$defs/interior"
        },
        "auto_assemblies": {
          "type": "array",
          "minItems": 1,
          "maxItems": 15,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "members",
              "origin_mm",
              "shape",
              "axis",
              "choices",
              "interior"
            ],
            "properties": {
              "id": {
                "$ref": "#/$defs/id"
              },
              "members": {
                "type": "array",
                "uniqueItems": true,
                "items": {
                  "$ref": "#/$defs/id"
                }
              },
              "origin_mm": {
                "$ref": "#/$defs/point"
              },
              "shape": {
                "$ref": "#/properties/layout/properties/shape"
              },
              "axis": {
                "$ref": "#/properties/layout/properties/axis"
              },
              "choices": {
                "$ref": "#/properties/layout/properties/choices"
              },
              "interior": {
                "$ref": "#/$defs/interior"
              }
            }
          }
        },
        "fixed_assemblies": {
          "type": "array",
          "minItems": 1,
          "maxItems": 15,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "members",
              "origin_mm",
              "interior"
            ],
            "properties": {
              "id": {
                "$ref": "#/$defs/id"
              },
              "members": {
                "type": "array",
                "uniqueItems": true,
                "items": {
                  "$ref": "#/$defs/id"
                }
              },
              "origin_mm": {
                "$ref": "#/$defs/point"
              },
              "interior": {
                "$ref": "#/$defs/interior"
              }
            }
          }
        },
        "placement": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "axis",
            "assembly_first",
            "rotations_deg"
          ],
          "properties": {
            "mode": {
              "enum": [
                "row",
                "corner",
                "shelves",
                "bottom-left",
                "stack_z"
              ]
            },
            "axis": {
              "enum": [
                "x",
                "y"
              ]
            },
            "assembly_first": {
              "type": "boolean"
            },
            "rotations_deg": {
              "type": "array",
              "items": {
                "enum": [
                  0,
                  90
                ]
              }
            },
            "sequence": {
              "type": "array",
              "items": {
                "type": "integer",
                "minimum": -16,
                "maximum": 3
              }
            },
            "split": {
              "type": "integer",
              "minimum": 1,
              "maximum": 4
            }
          },
          "allOf": [
            {
              "if": {
                "properties": {
                  "layout": {
                    "anyOf": [
                      {
                        "required": [
                          "shape"
                        ],
                        "properties": {
                          "shape": {
                            "pattern": "^hybrid-"
                          }
                        }
                      },
                      {
                        "required": [
                          "auto_assemblies"
                        ],
                        "properties": {
                          "auto_assemblies": {
                            "contains": {
                              "required": [
                                "shape"
                              ],
                              "properties": {
                                "shape": {
                                  "pattern": "^hybrid-"
                                }
                              }
                            }
                          }
                        }
                      }
                    ]
                  }
                }
              },
              "then": {
                "properties": {
                  "algorithm": {
                    "const": "compact-guillotine-v10"
                  }
                }
              }
            },
            {
              "if": {
                "required": [
                  "mode"
                ],
                "properties": {
                  "mode": {
                    "const": "shelves"
                  }
                }
              },
              "then": {
                "required": [
                  "sequence",
                  "split"
                ]
              }
            },
            {
              "if": {
                "required": [
                  "mode"
                ],
                "properties": {
                  "mode": {
                    "const": "bottom-left"
                  }
                }
              },
              "then": {
                "required": [
                  "sequence"
                ]
              }
            },
            {
              "if": {
                "required": [
                  "mode"
                ],
                "properties": {
                  "mode": {
                    "const": "stack_z"
                  }
                }
              },
              "then": {
                "required": [
                  "sequence"
                ]
              }
            }
          ]
        },
        "containers": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "origin_mm",
              "rotation_deg"
            ],
            "properties": {
              "id": {
                "$ref": "#/$defs/id"
              },
              "origin_mm": {
                "$ref": "#/$defs/point"
              },
              "rotation_deg": {
                "enum": [
                  0,
                  90
                ]
              }
            }
          }
        }
      }
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "algorithm": {
            "enum": [
              "compact-guillotine-v10",
              "compact-guillotine-v9",
              "compact-guillotine-v8",
              "compact-guillotine-v7",
              "compact-guillotine-v6",
              "compact-guillotine-v5",
              "compact-guillotine-v4"
            ]
          }
        }
      },
      "then": {
        "required": [
          "original_material",
          "original_manufacturing",
          "evaluation"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "layout": {
            "required": [
              "placement"
            ],
            "properties": {
              "placement": {
                "required": [
                  "mode"
                ],
                "properties": {
                  "mode": {
                    "const": "shelves"
                  }
                }
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "algorithm": {
            "enum": [
              "compact-guillotine-v5",
              "compact-guillotine-v6",
              "compact-guillotine-v7",
              "compact-guillotine-v8",
              "compact-guillotine-v9",
              "compact-guillotine-v10"
            ]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "layout": {
            "required": [
              "placement"
            ],
            "properties": {
              "placement": {
                "required": [
                  "mode"
                ],
                "properties": {
                  "mode": {
                    "const": "bottom-left"
                  }
                }
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "algorithm": {
            "enum": [
              "compact-guillotine-v6",
              "compact-guillotine-v7",
              "compact-guillotine-v8",
              "compact-guillotine-v9",
              "compact-guillotine-v10"
            ]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "layout": {
            "required": [
              "auto_assemblies"
            ]
          }
        }
      },
      "then": {
        "properties": {
          "algorithm": {
            "enum": [
              "compact-guillotine-v7",
              "compact-guillotine-v8",
              "compact-guillotine-v9",
              "compact-guillotine-v10"
            ]
          }
        }
      }
    }
  ],
  "$defs": {
    "id": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$",
      "maxLength": 80
    },
    "sha256": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "length": {
      "type": "number",
      "minimum": 0,
      "maximum": 2000,
      "multipleOf": 0.001
    },
    "point": {
      "type": "array",
      "prefixItems": [
        {
          "$ref": "#/$defs/length"
        },
        {
          "$ref": "#/$defs/length"
        }
      ],
      "items": false,
      "minItems": 2
    },
    "size3": {
      "type": "array",
      "prefixItems": [
        {
          "$ref": "#/$defs/length"
        },
        {
          "$ref": "#/$defs/length"
        },
        {
          "$ref": "#/$defs/length"
        }
      ],
      "items": false,
      "minItems": 3
    },
    "interior": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "id",
            "clear_mm",
            "kind"
          ],
          "properties": {
            "id": {
              "$ref": "#/$defs/id"
            },
            "clear_mm": {
              "$ref": "#/$defs/size3"
            },
            "kind": {
              "const": "compartment"
            },
            "contents": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/id"
              }
            },
            "access_cutout": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "wall",
                "diameter_mm"
              ],
              "properties": {
                "wall": {
                  "enum": [
                    "front",
                    "back",
                    "left",
                    "right"
                  ]
                },
                "diameter_mm": {
                  "$ref": "#/$defs/length"
                }
              }
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "id",
            "clear_mm",
            "kind",
            "axis",
            "first",
            "second"
          ],
          "properties": {
            "id": {
              "$ref": "#/$defs/id"
            },
            "clear_mm": {
              "$ref": "#/$defs/size3"
            },
            "kind": {
              "const": "split"
            },
            "axis": {
              "enum": [
                "x",
                "y"
              ]
            },
            "first": {
              "$ref": "#/$defs/interior"
            },
            "second": {
              "$ref": "#/$defs/interior"
            }
          }
        }
      ]
    }
  }
}
