#!/usr/bin/perl

use 5.012;
no warnings "experimental";

use File::Find::Wanted qw(find_wanted);
use Spp::Builtin qw(read_file write_file to_json clean_ast);
use Mylisp qw(mylisp_to_ast);
use Mylisp::Core qw(change_sufix);
use Mylisp::ToPerl qw(ast_to_perl tidy_perl);
use Mylisp::Stable;

my $action = $ARGV[0];
my $file   = $ARGV[1];
given ($action) {
   when ('--repl')   { Mylisp::repl() }
   when ('--update') { Mylisp::update() }
   when ('--json')   { ast_to_json($file) }
   when ('--perl')   { to_perl($file) }
   when ('--lint')   { lint_dir($file) }
   when ('--tidy'  ) { tidy_dir($file) }
   default {
      say "
      ## REPL mode
      mylisp --repl

      ## update grammar define in Spp/Grammar.pm
      mylisp --update

      ## transfer mylisp file/dir to Ast Json file.
      mylisp --json  file-or-dir

      ## transfer mylisp file/dir to perl.file
      mylisp --perl file-or-dir

      ## check mylisp file or dir syntax error.
      mylisp --lint file-or-dir

      ## tidy perl .pl|.pm file|dir
      mylisp --tidy file-or-dir"
      ;
   }
}

sub lint_dir {
   my $dir = shift;
   if (-d $dir) {
      my @files = find_wanted(sub {/\.spp$/}, $dir);
      for my $file (@files) {
         say "lint $file ...";
         lint_file($file);
      }
   } elsif (-e $file) {
      lint_file($file);
   }
}      

sub lint_file {
   my $file = shift;
   my $text = read_file($file);
   my $ast  = mylisp_to_ast($text);
   my $stable = Mylisp::Stable->new($text);
   $stable->lint_ast($ast);   
   ast_to_perl(clean_ast($ast));
}

sub to_perl {
   my $dir = shift;
   if (-d $dir) {
      my @files = find_wanted(sub {/\.spp$/}, $dir);
      for my $file (@files) {
         print "mylisp to perl .. ";
         file_to_perl($file);
      }
   } elsif (-e $file) {
      file_to_perl($file)
   }
}      

sub file_to_perl {
   my $file = shift;
   my $text = read_file($file);
   my $ast  = mylisp_to_ast($text);
   my $stable = Mylisp::Stable->new($text);
   $stable->lint_ast($ast);
   $ast = clean_ast($ast);
   my $perl_str = ast_to_perl($ast);
   my $perl_file = change_sufix($file,'spp','spp.pm');
   write_file($perl_file, $perl_str);
}

sub tidy_dir {
   my $dir = shift;
   if (-d $dir) {
      my @files = find_wanted(sub {/\.p[ml]$/}, $dir);
      for my $file (@files) {
         print "tidy file: $file .. ";
         tidy_file($file)
      }
   } elsif (-e $dir) { tidy_file($dir) }
}

sub tidy_file {
   my $file = shift;
   my $text = read_file($file);
   my $tidy_text = tidy_perl($text);
   rename($file, "$file.bak");
   write_file($file, $tidy_text);
}

sub ast_to_json {
   my $dir = shift;
   if (-d $dir) {
      my @files = find_wanted(sub {/\.p[ml]$/}, $dir);
      for my $file (@files) {
         print "mylisp Ast to Json file: $file .. ";
         ast_to_json_file($file)
      }
   } elsif (-e $dir) { ast_to_json_file($dir) }
}

sub ast_to_json_file {
   my $file = shift;
   my $text = read_file($file);
   my $ast  = mylisp_to_ast($text);
   my $json_file = change_sufix($file,'spp','json');
   write_file($json_file, to_json(clean_ast($ast)));
}

