#!/usr/bin/env perl

use 5.012;
use strict;
use warnings;

use JSON;
use IPC::Open2;

my @markdown = qw/cmark --smart --safe/;

my $question;
my $single_choice;
my $source;
my $media;
my %last_option;
my @options;
my @questions = ();

sub md {    # pipe through $markdown
  my ($input) = @_;
  my $pid = open2(\*OUT, \*IN, @markdown)
    or die "open2() failed $!";
  print IN $input;
  close(IN);
  waitpid($pid, 0);

  return do { local $/; <OUT> };
}

sub add {
  return unless %last_option;

  if (defined $last_option{"comment"}) {
    $last_option{"comment"} = md($last_option{"comment"});
  }
  
  push(@options, {%last_option});
}

while (<>) {
  chomp;
  if (/^.$/) {
    add();

    die "end of block without a question at line $.\n"
      unless defined $question;

    my %ent =
      (
       "question" => md($question),
       "options"  => [@options],
       "multiple" => ($single_choice eq "0" ? \0 : \1)
      );
    $ent{"source"} = $source if defined $source;
    $ent{"media"}  = $media  if defined $media;

    push(@questions, { %ent });
    undef $question;
    undef $single_choice;
    undef $source;
    undef $media;
    undef %last_option;
    undef @options;
  } elsif (/^([01])(.*?)(?:\(([^()]*)\))?$/) {
    $single_choice = $1;

    $question = $2;
    chomp $question;

    $source = $3;
    chomp $source if $source;
  } elsif (/^@(.*)/) {
    $media = $1;
    chomp $media;
  } elsif (/^([-+?])\s*(.*)/) {
    add();
    %last_option =
      (
       "option"  => $2,
       "correct" => $1 eq "+" ? JSON::true : $1 eq "-" ? JSON::false : JSON::null
      );
  } elsif (/^.+$/) {		# non-empty line
    $last_option{"comment"} .= "$_\n";
  }
}

say (to_json [@questions]);