use strict;
use warnings;

use Test::More;

use lib "t/lib";
use TestUtil::MyLib;

use File::Basename 'basename';
use File::Path 'mkpath', 'rmtree';
use File::Spec;
use JSON::PP;

use SPVM::Builder::Util;
use SPVM::Builder;

my $inc_dir = "$FindBin::Bin/lib";
my $build_dir = $ENV{SPVM_BUILD_DIR};

# Failed to parse options.
{
  {
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps --not-exist t/08_spvmcc/script/myapp.spvm);
    my $status = system($spvmcc_cmd);
    isnt($status, 0);
  }
}

# Basic
{
  {
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib t/08_spvmcc/script/myapp.spvm);
    my $output = `$spvmcc_cmd`;
    
    like($output, qr|^SPVM$|m);
    like($output, qr|^TestCase::NativeAPI2$|m);
    like($output, qr|^TestCase::Precompile$|m);
    like($output, qr|^Byte$|m);
    like($output, qr|\x0A$|s);
  }
  
  # --with-version
  {
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --with-version t/08_spvmcc/script/myapp.spvm);
    my $output = `$spvmcc_cmd`;
    
    like($output, qr|^SPVM [\.\d]+$|m);
    like($output, qr|^TestCase::NativeAPI2 1\.002$|m);
    like($output, qr|^TestCase::Precompile 2\.005$|m);
    like($output, qr|^Byte \(version_from SPVM\)$|m);
    like($output, qr|\x0A$|s);
  }
  
  # --exclude
  {
    {
      my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --exclude TestCase::Precompile t/08_spvmcc/script/myapp.spvm);
      my $output = `$spvmcc_cmd`;
      
      like($output, qr|^SPVM$|m);
      like($output, qr|^TestCase::NativeAPI2$|m);
      unlike($output, qr|TestCase::Precompile|m);
      like($output, qr|^Byte$|m);
      like($output, qr|\x0A$|s);
    }
    
    {
      my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --exclude TestCase::NativeAPI2 --exclude TestCase::Precompile t/08_spvmcc/script/myapp.spvm);
      my $output = `$spvmcc_cmd`;
      
      like($output, qr|^SPVM$|m);
      unlike($output, qr|^TestCase::NativeAPI2$|m);
      unlike($output, qr|TestCase::Precompile|m);
      like($output, qr|^Byte$|m);
      like($output, qr|\x0A$|s);
    }
    
    {
      my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --exclude TestCase::* t/08_spvmcc/script/myapp.spvm);
      my $output = `$spvmcc_cmd`;
      
      like($output, qr|^SPVM$|m);
      unlike($output, qr|^TestCase::NativeAPI2$|m);
      unlike($output, qr|TestCase::Precompile|m);
      like($output, qr|^Byte$|m);
      like($output, qr|\x0A$|s);
    }
    
  }
}

# --cpanm
{
  # --cpanm
  {
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --cpanm t/08_spvmcc/script/myapp.spvm);
    my $output = `$spvmcc_cmd`;
    
    warn "[Test Output]\n$output";
    
    like($output, qr|^cpanm SPVM$|m);
    like($output, qr|^cpanm SPVM::TestCase::NativeAPI2$|m);
    like($output, qr|^cpanm SPVM::TestCase::Precompile$|m);
    unlike($output, qr|SPVM::Byte|m);
    like($output, qr|\x0A$|s);
  }
  
  # --cpanm, --with-version
  {
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --cpanm --with-version t/08_spvmcc/script/myapp.spvm);
    my $output = `$spvmcc_cmd`;
    
    warn "[Test Output]\n$output";
    
    like($output, qr|^cpanm SPVM\@[\.\d]+$|m);
    like($output, qr|^cpanm SPVM::TestCase::NativeAPI2\@1\.002$|m);
    like($output, qr|^cpanm SPVM::TestCase::Precompile\@2\.005$|m);
    unlike($output, qr|SPVM::Byte|m);
    like($output, qr|\x0A$|s);
  }
}

# --cpanfile
{
  # --cpanfile
  {
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --cpanfile t/08_spvmcc/script/myapp.spvm);
    my $output = `$spvmcc_cmd`;
    
    warn "[Test Output]\n$output";
    
    like($output, qr|^requires 'SPVM';$|m);
    like($output, qr|^requires 'SPVM::TestCase::NativeAPI2';$|m);
    like($output, qr|^requires 'SPVM::TestCase::Precompile';$|m);
    unlike($output, qr|SPVM::Byte|m);
    like($output, qr|\x0A$|s);
  }
  
  # --cpanfile, --with-version
  {
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --cpanfile --with-version t/08_spvmcc/script/myapp.spvm);
    my $output = `$spvmcc_cmd`;
    
    warn "[Test Output]\n$output";
    
    like($output, qr|^requires 'SPVM', '== [\.\d]+';$|m);
    like($output, qr|^requires 'SPVM::TestCase::NativeAPI2', '== 1\.002';$|m);
    like($output, qr|^requires 'SPVM::TestCase::Precompile', '== 2\.005';$|m);
    unlike($output, qr|SPVM::Byte|m);
    like($output, qr|\x0A$|s);
  }
}

# --json
{
  # --json
  {
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --json t/08_spvmcc/script/myapp.spvm);
    my $output = `$spvmcc_cmd`;
    
    like($output, qr|^  \{"class_name":"SPVM"\}|m);
    like($output, qr|^  \{"class_name":"TestCase::NativeAPI2"\}|m);
    like($output, qr|^  \{"class_name":"TestCase::Precompile"\}|m);
    like($output, qr|^  \{"class_name":"Byte"\}|m);
    like($output, qr|\x0A$|s);
    
    my $class_infos = JSON::PP::decode_json($output);
    
    ok($class_infos);
    
    is($class_infos->[0]{class_name}, "Address");
    
  }
  
  # --json, --with-version
  {
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --json --with-version t/08_spvmcc/script/myapp.spvm);
    my $output = `$spvmcc_cmd`;
    
    like($output, qr|^  \{"class_name":"SPVM","version":"[\.\d]+"\}|m);
    like($output, qr|^  \{"class_name":"TestCase::NativeAPI2","version":"1\.002"\}|m);
    like($output, qr|^  \{"class_name":"TestCase::Precompile","version":"2\.005"\}|m);
    like($output, qr|\x0A$|s);
    
    my $class_infos = JSON::PP::decode_json($output);
    
    ok($class_infos);
    
    is($class_infos->[0]{class_name}, "Address");
    is($class_infos->[0]{version_from}, "SPVM");
    
    my ($class_info_testcase_precompile) = grep { $_->{class_name} eq "TestCase::Precompile"} @$class_infos;
    is($class_info_testcase_precompile->{version}, "2.005");
  }
}

{
  # --resource-info
  {
    $ENV{"SPVM__TEST__MYAPP__EXE"} = 1;
    my $spvmcc_cmd = qq($^X -Mblib blib/script/spvmdeps -I $inc_dir -I t/02_vm/lib --resource-info t/08_spvmcc/script/myapp.spvm);
    my $output = `$spvmcc_cmd`;
    like($output, qr|\Q[TestCase::NativeAPI2]|);
    like($output, qr|TestCase::Resource::Mylib1|);
    like($output, qr|TestCase::Resource::Mylib2|);
    like($output, qr|\Q[TestCase::Precompile]|);
  }
}

done_testing;
