#!/usr/bin/env raku

use lib 'lib';
use Terminal::ANSI;
use Terminal::ANSI::OO;

my $version = q:x[jq -r .version META6.json].trim or exit note 'no version';
my $repo-base = "https://git.sr.ht/~bduggan/raku-terminal-ansi/tree/$version";

sub wrap($txt,Int :$cols = 80) {
  with run <<fmt -w $cols>>, :in, :out {
    .in.put: $txt;
    .in.close;
    .out.slurp(:close).trim;
  }
}

sub to-md($pod) {
  return Nil without $pod;
  my $out;
  for $pod.contents {
    when Pod::Block::Code {
      for .contents.lines {
         $out ~= .trim.indent(4) ~ "\n";
      }
    }
    when Pod::Block::Para {
      $out ~= wrap(.contents) ~ "\n\n";
    }
    default {
      warn "no handler for $_";
      $out ~= .Str;
    }
  }
  $out;
}

sub get-exports($module) {
  use MONKEY-SEE-NO-EVAL;
  my @lines;
  my $sym = EVAL "{$module}::EXPORT::DEFAULT::";
  for $sym.keys -> $sub {
    my $s = $sym{$sub};
    @lines.push: {
      label => ($s.name ~ $s.signature.gist),
      desc => $s.WHY.Str,
      line => $s.WHY.WHEREFORE.line,
      file => $s.WHY.WHEREFORE.file,
    }
  }
  @lines;
}

sub function-docs($module) {
  my @out;
  my @lines = get-exports($module);
  for @lines.sort: *.<label> -> $l {
    @out.push: '[' ~ $l<label> ~ ']'
    ~ '(' ~
      $repo-base ~ $l<file>.words[0].subst("$*CWD",'')~ '#L' ~ $l<line>
    ~ ') ' ~ $l<desc>;
    @out.push: '';
  }
  @out;
}

sub exporter-docs($module) {
  my $file = 'lib/' ~ ($module.split('::').join('/')) ~ '.md';
  note "writing $file";
  my @out;
  @out.push: "## $module";
  @out.push: "";
  @out.append: Terminal::ANSI.WHY.Str.split(/'─'/).map: *.trim;
  @out.push: "";
  @out.push: "## Exported Functions";
  @out.push: "";
  @out.append: function-docs($module);
  $file.IO.spurt: @out.join("\n");
}

sub class-docs(Str $class-str) {
  my $class = ::("$class-str");
  my $file = 'lib/' ~ ($class-str.split('::').join('/')) ~ '.md';
  note "writing $file";
  my %blocks = $class.pod.map: { (.?name // '') => $_ };
  my $class-name = to-md(%blocks<NAME>) // exit note "missing name for $class-str";
  my $syn = to-md(%blocks<SYNOPSIS>) // exit note "missing synposis for $class-str";
  my $desc = to-md(%blocks<DESCRIPTION>) // exit note "missing desc for $class-str";
  my @out;
  @out.push: "## NAME";
  @out.push: "";
  @out.push: "$class-name";
  @out.push: "## SYNOPSIS";
  @out.push: "";
  @out.push: $syn;
  @out.push: "## DESCRIPTION";
  @out.push: "";
  @out.push: $desc;
  @out.push: "";
  $file.IO.spurt: @out.join("\n");
}

sub MAIN {
  exporter-docs("Terminal::ANSI");
  class-docs("Terminal::ANSI::OO");
}

