use 5.010;
use alienfile;
use Sort::Versions;
use Path::Tiny qw /path/;


my $on_windows = $^O =~ /mswin/i;
my $on_automated_rig
  =  $ENV{PERL_CPAN_REPORTER_DIR}
  || $ENV{PERL_CPAN_REPORTER_CONFIG}
  || $ENV{AUTOMATED_TESTING}
  || $ENV{TRAVIS}
  || $ENV{APPVEYOR}
  || $ENV{CI};


use Cwd;
my $base_dir = getcwd();

#  make libtool noisy for debug purposes
#$ENV{LTFLAGS} = "--debug --verbose" if $on_windows;

use Env qw { @PATH };


my $min_target_version = '3.26.0';

plugin 'PkgConfig' => (
    pkg_name => 'sqlite3',
    minimum_version => $min_target_version,
);

plugin 'Probe::CommandLine' => (
  command  => 'sqlite3',
  #args    => [ '--version' ],
  #match   => qr/\d+\.\d+\.\d+ \d{4}-\d{2}-\d{2}/,
  #version => qr/gzip ([0-9\.]+)/,
  secondary => 1,  #  secondary to pkgconf probe
);

#  need to check if we have sqlite headers
#  as dependent aliens like proj need them
#probe sub {
#  my($build) = @_;  # $build is the Alien::Build instance.
#  system 'pkg-config --exists libfoo';
#  $? == 0 ? 'system' : 'share';
#};


share {

  my $with_local = '';
  my $with_cpp11 = '';

  #  need to work out how to get latest without updating next lines
  start_url 'https://www.sqlite.org/2022/sqlite-autoconf-3390300.tar.gz';
  plugin Download => (
    version => '3.39.3',
  );

  
  my $lib_version = get_lib_version() // 'not yet defined';
  say "Downloaded version is $lib_version";
  
  plugin Extract => (format => 'tar.gz');


  plugin 'Build::Autoconf' => ();

  my $build_static = ($^O =~ /mswin/i) ? '' : '--disable-shared';
  $build_static = '';
  $build_static = '--enable-static=no';  #  override - needed?  leftover from gdal
  $build_static = '' if $ENV{FORCE_DYNAMIC};
  
  
  if ($^O =~ /bsd/) {
    plugin 'Build::Make' => 'gmake';
    if (-d '/usr/local') {
        $with_local = ' --with-local=/usr/local ';
    }
  }
  elsif ($^O =~ /dragonfly/) {
    #  might need to be combined with bsd check above
    #  but not sure if /usr/local is needed yet
    plugin 'Build::Make' => 'gmake';
  }

  my $make_cmd = '%{make}';
  my $make_inst_cmd = '%{make} install';
  my @make_clean;
  #  try not to exceed the cpan-testers log limits
  if ($on_automated_rig) {
    say "Running under CI or automated testing";
    $make_cmd      .= q/ | perl -ne "BEGIN {$|=1; open our $log, q|>|, q|build.log|};   print qq|\n| if 0 == ($. %% 100); print q|.|; print {$log} $_;" || type build.log/;
    $make_inst_cmd .= q/ | perl -ne "BEGIN {$|=1; open our $log, q|>|, q|install.log|}; print qq|\n| if 0 == ($. %% 100); print q|.|; print {$log} $_;" || type install.log/;
    if (!$on_windows) {
        $make_cmd =~ s/%%/%/;
        $make_cmd =~ s/type/cat/;
        $make_cmd =~ s/"/'/g;
        $make_inst_cmd =~ s/%%/%/;
        $make_inst_cmd =~ s/type/cat/;
        $make_inst_cmd =~ s/"/'/g;
    }
    #if (! ($ENV{TRAVIS} || $ENV{APPVEYOR})) {
    #    push @make_clean, '%{make} clean';
    #}
    #  clean up the build dir on cpan testers etc
    plugin 'Cleanse::BuildDir';
  }
  
  meta->around_hook( build => \&remove_gitfw_from_path );
  meta->around_hook(
    build => sub {
      my ($orig, $build, @args) = @_;
      $build->log("Setting CCACHE_BASEDIR to " . getcwd());
      local $ENV{CCACHE_BASEDIR} = getcwd();
      $orig->($build, @args);
    }
  );

  build [
    "%{configure} $with_local $with_cpp11 $build_static",
    \&pause,
    $make_cmd,
    $make_inst_cmd,
    #@make_clean,
  ];

};

#  git for windows clashes with MSYS
#  if its /usr/bin dir is in the path
sub remove_gitfw_from_path {
  my ($orig, $build, @args) = @_;

  return $orig->($build, @args)
    if !$on_windows;

  local $ENV{PATH} = $ENV{PATH};

  my $msys_path = eval {
    path('Alien::MSYS'->msys_path())
  };
  return if !defined $msys_path;
  my $count = @PATH;

  @PATH
    = grep {path($_)->stringify =~ m|/usr/bin$| && path($_) ne $msys_path ? () : $_}
      grep {defined $_}  #  undef paths cause issues with Path::Tiny 
      @PATH;

  my $removed = $count - @PATH;
  if ($removed) {
    $build->log ("$removed additional .../usr/bin dirs were removed from the path for compilation");
  }

  $orig->($build, @args);
}

sub pause {
    return;  #  re-enable in case of debug
    return if $on_automated_rig;
    return if !$on_windows;

    say "CONTINUE?";
    my $response = <>;
    while (not $response =~ /yes/) {
        $response = <>;
    }
}


sub get_lib_version {
    my $h = get_alien_state_hash();
    return $h->{runtime}{version};
}

sub get_alien_state_hash {
    use JSON::PP;
    my $root = "$base_dir/_alien";
    my $f = "$root/state.json";
    my $h = {};
    if (-e $f) {
        open my $fh, '<', $f or die $!;
        my $d = do {
            local $/ = undef;
            <$fh>;
        };
        $h = JSON::PP::decode_json($d);
    }
    return $h;
}