// File: hzeller[P]jcxxgen/schema-compiler.cc
// Function: main
int main(int argc, char *argv[]) {
  if (argc < 2) {
    fprintf(stderr, "usage: %s [options] <protocol-spec-yaml>\n", argv[0]);
    fprintf(stderr, "Options:\n"
            "  -o <filename>     : Output to filename\n"
            "  -j <json-include> : Include path to json.hpp, "
            "including brackets <> or quotes \"\" around.\n"
            "                      Default: '<nlohmann/json.hpp>'\n");
    return 1;
  }

  const char *out_filename = nullptr;
  const char *nlohmann_json_include = "<nlohmann/json.hpp>";
  int opt;
  while ((opt = getopt(argc, argv, "o:")) != -1) {
    switch (opt) {
    case 'o': out_filename = strdup(optarg); break;
    case 'j': nlohmann_json_include = strdup(optarg); break;
    }
  }

  const char *schema_filename = argv[optind];
  auto objects = LoadObjectTypes(schema_filename);
  if (!objects) {
    fprintf(stderr, "Couldn't parse spec\n");
    return 2;
  }

  FILE *out = stdout;
  if (out_filename) {
    out = fopen(out_filename, "w");
    if (!out) {
      perror("opening output file");
      return 3;
    }
  }

  GenerateCode(schema_filename, nlohmann_json_include, *objects, out);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
jge 0x7b72
movq 0x4c47a(%rip), %rax     # 0x53fb0
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rdx
leaq 0x30956(%rip), %rsi     # 0x3849d
movb $0x0, %al
callq 0x5570
movq 0x4c45b(%rip), %rax     # 0x53fb0
movq (%rax), %rdi
leaq 0x30968(%rip), %rsi     # 0x384c7
movb $0x0, %al
callq 0x5570
movl $0x1, -0x4(%rbp)
jmp 0x7cf3
movq $0x0, -0x18(%rbp)
leaq 0x30a09(%rip), %rax     # 0x3858a
movq %rax, -0x20(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x30a0b(%rip), %rdx     # 0x3859e
callq 0x50d0
movl %eax, -0x24(%rbp)
cmpl $-0x1, %eax
je 0x7be1
movl -0x24(%rbp), %eax
movl %eax, -0x58(%rbp)
subl $0x6a, %eax
je 0x7bcc
jmp 0x7bad
movl -0x58(%rbp), %eax
subl $0x6f, %eax
jne 0x7bdf
jmp 0x7bb7
movq 0x4c3ca(%rip), %rax     # 0x53f88
movq (%rax), %rdi
callq 0x56c0
movq %rax, -0x18(%rbp)
jmp 0x7bdf
movq 0x4c3b5(%rip), %rax     # 0x53f88
movq (%rax), %rdi
callq 0x56c0
movq %rax, -0x20(%rbp)
jmp 0x7b85
movq -0x10(%rbp), %rax
movq 0x4c3cc(%rip), %rcx     # 0x53fb8
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x58b0
leaq -0x38(%rbp), %rdi
callq 0x83b0
testb $0x1, %al
jne 0x7c3c
movq 0x4c398(%rip), %rax     # 0x53fb0
movq (%rax), %rdi
leaq 0x3097f(%rip), %rsi     # 0x385a1
movb $0x0, %al
callq 0x5570
movl $0x2, -0x4(%rbp)
movl $0x1, -0x3c(%rbp)
jmp 0x7cea
movq 0x4c32d(%rip), %rax     # 0x53f70
movq (%rax), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x7cad
movq -0x18(%rbp), %rdi
leaq 0x3095a(%rip), %rsi     # 0x385b6
callq 0x5490
movq %rax, -0x60(%rbp)
jmp 0x7c67
movq -0x60(%rbp), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x7cab
leaq 0x3093b(%rip), %rdi     # 0x385b8
callq 0x5350
jmp 0x7c84
movl $0x3, -0x4(%rbp)
movl $0x1, -0x3c(%rbp)
jmp 0x7cea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x7e40
jmp 0x7cff
jmp 0x7cad
movq -0x30(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x70(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x83e0
movq %rax, -0x68(%rbp)
jmp 0x7ccc
movq -0x68(%rbp), %rdx
movq -0x70(%rbp), %rsi
movq -0x78(%rbp), %rdi
movq -0x48(%rbp), %rcx
callq 0x6e10
jmp 0x7ce3
movl $0x0, -0x3c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x7e40
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x5680
nopl (%rax,%rax)