use 5.010;
use warnings;
use alienfile;
use Sort::Versions;
use Env qw /@PATH @LD_LIBRARY_PATH @DYLD_LIBRARY_PATH @PROJ_LIB/;
use Path::Tiny qw /path/;
use List::Util;
use FFI::CheckLib;

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};

my @alien_deps = qw(
        Alien::geos::af
        Alien::proj
        Alien::sqlite
        Alien::libtiff
  );

#  make sure we get GEOS, PROJ and other support
foreach my $alien (@alien_deps) {
  eval "require $alien";
  my $e = $@;
  warn $e if $e;
  if (!$e && $alien->install_type eq 'share') {
    log "Prepending $alien bin dir to path";
    unshift @PATH, $alien->bin_dir;
  }
}
my $have_spatialite = eval 'require
  Alien::spatialite';
if ($have_spatialite && Alien::spatialite->version ge 5) {
  if (!$on_windows and Alien::spatialite->install_type('share')
      and $Alien::spatialite::VERSION lt 1.06) {
    $have_spatialite = undef;  #  rpath issues before this
  }
  else {
    log "Prepending Alien::spatialite bin dir to path";
    unshift @PATH, Alien::spatialite->bin_dir;
    push @alien_deps, 'Alien::spatialite';
  }
}
else {
  $have_spatialite = undef;
}

#  configure script does not seem to detect the proj lib distributed with Strawberry perl
#use FFI::CheckLib;
#my $proj_lib = FFI::CheckLib::find_lib (lib => 'proj');
Alien::Build->log ('$ENV{PROJ_LIB} IS ' . ($ENV{PROJ_LIB} // ''));


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


use Cwd;
my $base_dir = getcwd();
my $patch_file_isnan
  = "$base_dir/patch_isnan_gcc.patch";
my $patch_file_configure
  = "$base_dir/0001-Enable-shared-build-on-freebsd-10.patch";

my $min_target_version = '3.1.0';

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


share {

  #  add existing alien files to path etc
  #  not very elegant...
  #  disable for now - config tests fail
  #  it looks to be already noted in https://github.com/Perl5-Alien/Alien-Build/issues/12
  #  might also be able to access via old hash via https://metacpan.org/pod/Alien::Build#install_prop
  my $have_alien_gdal = eval 'require Alien::gdal';
  my $copy_from_dir;
  if ($ENV{ALIEN_SHARE_RECYCLE} && $have_alien_gdal && Alien::gdal->install_type eq 'share') {
      my $ag_version = Alien::gdal->version;
      say "Found existing gdal via alien ($ag_version) in " .  Alien::gdal->dist_dir;
      #  append the relevant path
      if (versioncmp($ag_version, $min_target_version) >= 0) {
        $copy_from_dir = Alien::gdal->dist_dir;
      }
  }

  if ($copy_from_dir) {
    #  files are copied in the extract hook
    meta->register_hook(download => sub {
      Path::Tiny->new ('fauxdownload.txt')->touch;
    });

    if($^O eq 'MSWin32') {
      meta->register_hook(extract => sub {
        my($build) = @_;
        $copy_from_dir =~ s|/|\\|g;  #  it seems that xcopy needs backslashes in paths
        $build->system("xcopy $copy_from_dir . /E /Q");
      });
    }
    else {
      meta->register_hook(extract => sub {
        my ($build) = @_;
        "cp -aR $copy_from_dir .";
      });
    }

    meta->after_hook( extract => sub {
      my($build) = @_;
      $build->log('CURRENTLY IN ' . cwd());
      File::Path::rmtree '_alien';
    });

    plugin 'Build::Copy';

  }
  else {
    my $with_local = '';
    my $with_cpp11 = '';
    
    requires 'Alien::cmake3';
    requires 'Alien::MSYS' if $on_windows;
    #requires 'Alien::patchelf' if !($on_windows || $^O =~ /darwin/i);
    
    Alien::Build->log ("Proj library version is " . Alien::proj->version);
    die "Proj version must be at least 6.0.0"
      if not Alien::proj->atleast_version ('6.0.0');  

    plugin 'Build::SearchDep' => (
      aliens   => [@alien_deps],
      public_I => 1,
      public_l => 1,
    );
  
    start_url 'https://download.osgeo.org/gdal/CURRENT';
    #start_url "file://$base_dir";  #  debug
    plugin Download => (
      filter  => qr/^gdal-([0-9\.]+)\.tar\.gz$/,
      version => qr/^gdal-([0-9\.]+)\.tar\.gz$/,
    );
  
    my $gdal_version = get_gdal_version() // 'not yet defined';
    say "Downloaded gdal version is $gdal_version";
    
    plugin Extract => (format => 'tar.gz');
  
    #plugin 'Build::Autoconf' => ();
    plugin 'Build::CMake' => ();
    
    #my $build_static = ($^O =~ /mswin/i) ? '' : '--disable-shared';
    #$build_static = '--enable-static=no';  #  override - HUGE files if static
    #$build_static = '' if $ENV{FORCE_DYNAMIC};
    my $build_static = '';
    
    
    if ($^O =~ /bsd|dragonfly/) {
      requires "Alien::gmake";
      plugin 'Build::Make' => 'gmake';
      #if (-d '/usr/local') {
          #$with_local = '--with-local=/usr/local';
      #}
      if (!-e '/usr/local/include/sqlite3.h' && Alien::sqlite->install_type eq 'system') {
        warn '/usr/local/include/sqlite3.h does not exist, '
           . 'you might need to install the sqlite package for your system, '
           . 'or install a share version of Alien::sqlite';
      }
    }
  
  
    my $make_cmd = '%{make}';
    my $make_inst_cmd = '%{make} install';  
    my @automated_rig_config_args;
    
    #  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} $_;" /;
      $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} $_;" /;
      if (!$on_windows) {
          $make_cmd =~ s/%%/%/;
          $make_cmd =~ s/"/'/g;
          $make_cmd .= ' || (E=$? && cat build.log && exit $E)';
          $make_inst_cmd =~ s/%%/%/;
          $make_inst_cmd =~ s/"/'/g;
          $make_inst_cmd .= ' || (E=$? && cat install.log && exit $E)';
      }
      else {
          #  fake exit codes on failure, not sure how to get originals
          $make_cmd      .= q/ || perl -e"system ('type', 'build.log'); exit 1"/;
          $make_inst_cmd .= q/ || perl -e"system ('type', 'install.log'); exit 1"/;
      }
  
      #  clean up the build dir on cpan testers etc
      plugin 'Cleanse::BuildDir';
    }
    
    my @with_args = (
      #https://gdal.org/build_hints.html#cmdoption-arg-GDAL_USE_-Packagename_in_upper_case-BOOL
      @automated_rig_config_args,
      '-DGDAL_USE_MSSQL_ODBC=OFF',
      '-DGDAL_USE_MSSQL_NCLI=OFF',
      '-DGDAL_USE_MYSQL=OFF',
      '-DBUILD_CSHARP_BINDINGS:BOOL=OFF',
      #'--without-pg',
      #'--without-ogdi',
      #'--with-mongocxxv3=no',
      #$^O eq 'MSWin32' ? '--without-hdf5' : (),  #  issues with strawberry perl hdf5 dlls
      '-DGDAL_SET_INSTALL_RELATIVE_RPATH=ON',
    );
    
    Alien::Build->log('LD_LIBRARY_PATH: ' . join ':', map {defined $_ ? $_ : ''} @LD_LIBRARY_PATH);
    my @ld_flags;
    my @ld_lib_path;
    #  system installs won't necessarily have dist dirs
    if (Alien::proj->install_type eq 'share') {
      push @with_args, '-DPROJ_INCLUDE_DIR=' . path (Alien::proj->dist_dir . '/include')->stringify;
      my $libfile = find_lib_file (
        lib   => 'proj',
        alien => 'Alien::proj',
      );
      #  windows proj has non-conformant lib name, libproj_9_0.dll
      #  and this fails the checks in FFI::CheckLib < 0.29
      if ($on_windows && !$libfile) {
        my @files = grep {/libproj/} glob (Alien::proj->bin_dir . '/*.dll');
        $libfile = shift @files;
        Alien::Build->log ("Secondary search for proj dynamic lib found $libfile");
      }
      push @with_args, '-DPROJ_LIBRARY_RELEASE=' . $libfile;
      
      my $proj_lib = Alien::proj->dist_dir . '/share/proj';
      warn "======\nno proj lib\n=====" if !-e $proj_lib;
      if (!grep {($_ // '')=~ /^$proj_lib$/} @PROJ_LIB) {
        Alien::Build->log ("Appending $proj_lib to \$ENV{PROJ_LIB}");
        push @PROJ_LIB, $proj_lib;
        Alien::Build->log ("PROJ_LIB is now $ENV{PROJ_LIB}");
      }
      if (!$on_windows) {
        my $dir = List::Util::first {-d $_} map {Alien::proj->dist_dir . "/$_"} (qw/lib lib64 lib32/);
        push @ld_lib_path, $dir if $dir;
      }
    }
    if (Alien::libtiff->install_type eq 'share') {
      my $libtiff_include = path ('Alien::libtiff'->dist_dir . '/include')->stringify;
      my $libfile = find_lib_file (
        lib   => 'tiff',
        alien => 'Alien::libtiff',
      );
      push @with_args, (
        "-DTIFF_LIBRARY=$libfile",
        "-DTIFF_INCLUDE_DIR=$libtiff_include",
      );
      if (!$on_windows) {
        push @ld_lib_path, (Alien::libtiff->dist_dir . '/lib');
      }
    }
    if ($have_spatialite && Alien::spatialite->install_type eq 'share') {
      #  need to check for this under cmake?
    }
    if (Alien::sqlite->install_type eq 'share') {
      my $sqlite_include = path ('Alien::sqlite'->dist_dir . '/include')->stringify;
      my $libfile = find_lib_file (
          lib   => 'sqlite3',
          alien => 'Alien::sqlite',
      );
      my $exe_extension = ($on_windows ? '.exe' : '');
      my $sqlite_exe = path ('Alien::sqlite'->dist_dir . "/bin/sqlite3$exe_extension");
      push @with_args, (
        "-DEXE_SQLITE3=$sqlite_exe",
        "-DSQLITE3_LIBRARY=$libfile",
        "-DSQLITE3_INCLUDE_DIR=$sqlite_include",
      );
      if (!$on_windows) {
        push @ld_lib_path, (Alien::sqlite->dist_dir . '/lib');
      }
    }
    if (Alien::geos::af->install_type eq 'share') {
      my $libfile = find_lib_file (
          lib   => 'geos',
          alien => 'Alien::geos::af',
      );
      push @with_args, '-DGEOS_INCLUDE_DIR=' . path(Alien::geos::af->dist_dir . '/include')->stringify;
      push @with_args, '-DGEOS_LIBRARY=' . $libfile;
      #  build weirdness on linux with geos under cmake
      if (!$on_windows) {
        my $dir = List::Util::first {-d $_} map {Alien::geos::af->dist_dir . "/$_"} (qw/lib lib64 lib32/);
        push @ld_lib_path, $dir if $dir;
      }
    }
    if ($^O eq 'MSWin32') {
      #  should add an env flag for this
      push @with_args, '-DGDAL_USE_CURL=OFF';
    }    
    
    my $config_args = $ENV{ALIEN_GDAL_CONFIG_ARGS} // '';
    $config_args =~ s/[^-\s\w,=+]//g;  #  overkill?
    $config_args = join (' ', @with_args) . " $config_args";
    
    meta->around_hook( build => \&remove_gitfw_from_path );
    plugin 'PkgConfig::PPWrapper';
    meta->around_hook(
      build => sub {
        my ($orig, $build, @args) = @_;
        $build->log("Setting CCACHE_BASEDIR to " . getcwd());
        local $ENV{CCACHE_BASEDIR} = getcwd();
        $orig->($build, @args);
      }
    );
    
    my @drivers_to_disable = get_drivers_to_disable();
    #  not sure this is needed, or if it is to deal with a cirrus quirk 
    #  hack
    if ($^O =~ /darwin/) {
      push @DYLD_LIBRARY_PATH, @ld_lib_path;
      Alien::Build->log('DYLD_LIBRARY_PATH: ' . join ':', @DYLD_LIBRARY_PATH);
    }
    else {
      push @LD_LIBRARY_PATH, @ld_lib_path;
      Alien::Build->log('LD_LIBRARY_PATH: ' . join ':', @LD_LIBRARY_PATH);
    }

    #foreach my $env_var (qw /LD_LIBRARY_PATH DYLD_LIBRARY_PATH LDFLAGS CFLAGS CXXFLAGS/) {
    #  say "ENV: $env_var is " . ($ENV{$env_var} // '');
    #}
    
    my $cmake_cmd = [
      '%{cmake}',
      -G => '%{cmake_generator}',
      '-DCMAKE_MAKE_PROGRAM=%{make}',
      #'-DBUILD_DOCUMENTATION=NO',
      '-DBUILD_TESTING=OFF',
      '-DBUILD_SHARED_LIBS=ON',
      @with_args,
      '-DBUILD_PROJSYNC=OFF',
      '-DCMAKE_INSTALL_PREFIX:PATH=%{.install.prefix}',
      '-DCMAKE_BUILD_TYPE=Release',
      '-DBUILD_PYTHON_BINDINGS:BOOL=OFF',
      @drivers_to_disable,
      '..'
    ];
    
    build [
      #\&pause,
      #\&cleanup_ldflags,
      'mkdir _build',
      'cd _build',
      $cmake_cmd,
      $make_cmd,
      \&patch_pkgconfig,
      $make_inst_cmd,
      \&patch_rpaths,
    ];
  }
};


sub find_lib_file {
  my %args = @_;
  
  my(@lib_files) = find_lib(
      %args,
      systempath => $args{alien} ? [] : undef,  #  only search the alien if one is passed
  );
  #  we grab the first, assuming they are
  #  all the same or point to the same origin
  my $libfile = $lib_files[0] // '';
  $libfile =~ s|\\|/|g if $on_windows;
  Alien::Build->log ("Found $args{lib} dynamic lib: $libfile");
  return $libfile;
}


sub patch_rpaths {
  my ($build) = @_;
  
  #  only run on unices - incomplete check but
  #  I don't think aliens work on VMS or zOS
  return if $on_windows;
  
  return patch_rpaths_macos($build)
    if $^O =~ /darwin/i;

  my $h = get_alien_state_hash();
  my $install_path = $h->{install}{prefix};
  return if !defined $install_path;

  my @alien_rpaths;
  for my $alien (@alien_deps) {
    next if not $alien->install_type('share');
    my $libdir;
    for my $tgt (qw/lib lib64 lib32/) { 
        $libdir = $alien->dist_dir . '/lib';
        last if -d $libdir;
    }
    $build->log ("Unable to locate lib dir for $alien, tried lib, lib64 and lib32.  Expect issues later on.")
      if !-d $libdir;
    push @alien_rpaths, $libdir;
  }
  if (!@alien_rpaths) {
    $build->log('No shared alien deps found, not updating rpaths');
    return;
  }

  eval 'require Alien::patchelf'
    or do {
      warn 'Unable to load Alien::patchelf, cannot update rpaths';
      return;
    };
  my $pe = Alien::patchelf->new;


  my $origin_string = $^O =~ /darwin/ ? '@loader_path' : '$ORIGIN';
  my $alien_rpath_text
    = join ':', (
       (map {$origin_string . '/../' . path ($_)->relative($install_path)->stringify} @alien_rpaths),
       @alien_rpaths
      );

  $build->log ("Prepending rpaths with $alien_rpath_text");


  my $dest_dir;
  if($build->meta_prop->{destdir})
  {
    $dest_dir = $ENV{DESTDIR};
  }
  $build->log('DEST DIR IS: ' . $dest_dir); 

  #  need to also do the bin dir - those files only need to have $ORIGIN/../lib added
  use File::Find::Rule;
  my (@so_files)
    = grep {not -l $_}
      File::Find::Rule
              ->file()
              ->name( qr/^libgdal.so/ )
              ->in( $dest_dir );
  
  foreach my $so_file (@so_files) {
    my ($old_rpath, $result, $stderr, @errors);
    ($old_rpath, $stderr, @errors)
      = $pe->patchelf ('--print-rpath', $so_file);
    $old_rpath //= '';
    #  prepend our paths
    my $rpath = $alien_rpath_text . ($old_rpath ? (':' . $old_rpath) : '');
    $build->log("Updating rpath for $so_file to $rpath, was $old_rpath");
    ($result, $stderr, @errors)
      = $pe->patchelf ('--set-rpath', $rpath, $so_file);
    warn $stderr if $stderr;
  }

#my $xy = <STDIN>;
  return;
}

sub patch_rpaths_macos {
  my ($build) = @_;
  
  #  just for safety
  return if not $^O =~ /darwin/i;

  my $h = get_alien_state_hash();
  my $install_path = $h->{install}{prefix};
  return if !defined $install_path;

  my @alien_rpaths;
  for my $alien (@alien_deps) {
    next if not $alien->install_type('share');
    push @alien_rpaths, $alien->dist_dir . '/lib';
  }
  if (!@alien_rpaths) {
    $build->log('No shared alien deps found, not updating rpaths');
    return;
  }

  use File::Which qw /which/;
  my $install_name_tool = which 'install_name_tool';
  if (!$install_name_tool) {
    $build->log('install_name_tool not found, not updating rpaths');
    return;
  }
  my $otool = which 'otool';
  if (!$install_name_tool) {
    $build->log('otool not found, not updating rpaths');
    return;
  }

  my $origin_string = '@loader_path';
  my @inst_tool_rpath_args
    = map {; '-add_rpath' => $_} (
       (map {"${origin_string}/../" . path ($_)->relative($install_path)->stringify} @alien_rpaths),
       @alien_rpaths,
      );

  my $dest_dir;
  if($build->meta_prop->{destdir})
  {
    $dest_dir = $ENV{DESTDIR};
  }
  $build->log('DEST DIR IS: ' . $dest_dir); 

  $build->log ("Prepending rpaths with args " . join ' ', @inst_tool_rpath_args);
  
  #  need to also do the bin dir - those files only need to have $ORIGIN/../lib added
  use File::Find::Rule;
  my (@so_files)
    = grep {not -l $_}
      File::Find::Rule
              ->file()
              ->name( qr/^libgdal[.\d]*.dylib/ )
              ->in( $dest_dir );
  
  foreach my $so_file (@so_files) {
    use Capture::Tiny qw /capture/;
    $build->log ("Updating rpath for $so_file");
    my ($otool_text, $old_rpath, $result, $stderr, @errors);
    $build ->log ("Calling: $otool, '-l', $so_file");
    #eval {
      ($otool_text, $stderr, @errors)
        = capture {system $otool, '-l', $so_file};
    #};
    #$build->log ($@) if $@;
    #$build->log (@errors) if @errors;
    $build->log ($stderr) if $stderr;
    #$build->log($otool_text);  #  debug
    
    #  now we need to extract the rpaths
    my @lines = split "\n", $otool_text;
    my @existing_paths;
    while (defined (my $line = shift @lines)) {
        if ($line =~ /RPATH/) {
            shift @lines;
            $line = shift @lines;
            $line =~ s/^\s+path\s//;
            $line =~ s/\s\(offset.+$//;
            push @existing_paths, $line;
        }
    }
    #  remove existing
    if (@existing_paths) {
      $build->log ("removing existing rpaths " . join ' ', @existing_paths);
      my @delete_args = map {; '-delete_rpath' => $_} @existing_paths;
      ($result, $stderr, @errors)
        = capture {system $install_name_tool, @delete_args, $so_file};
      #$build->log($result);
      $build->log($stderr) if $stderr;
    }

    #  now append the existing ones
    push @inst_tool_rpath_args, map {; '-add_rpath' => $_} @existing_paths;
    #  prepend our paths
    ($result, $stderr, @errors)
      = capture {system $install_name_tool, @inst_tool_rpath_args, $so_file};
    #$build->log($result);
    $build->log($stderr) if $stderr;
  }

  return;
}


#  we can get dangling -L values
#  bandaid until we find the source
sub cleanup_ldflags {
    my ($build, @args) = @_;

    if ($ENV{LDFLAGS} && $ENV{LDFLAGS} =~ /\s*-L\s*$/) {
        $build->log("Trimming trailing -L from $ENV{LDFLAGS}");
        $ENV{LDFLAGS} =~ s/\s*-L\s*$//;
    }

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


sub update_pkg_conf_path {
    return if !$on_windows;
    use Env qw /@PKG_CONFIG_PATH/;
    say 'Modifying drive paths in PKG_CONFIG_PATH';
    say $ENV{PKG_CONFIG_PATH};
    #  msys-ificate drive paths
    @PKG_CONFIG_PATH = map {my $x = $_; $x =~ s{^([a-z]):}{/$1}i; $x} @PKG_CONFIG_PATH;
    say $ENV{PKG_CONFIG_PATH};
    return;
}


#  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 ? () : $_}
      @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 patch_pkgconfig {
    #my $gdal_config_file = 'bin/gdal-config';
    #my $pkg_config_file  = 'lib/pkgconfig/gdal.pc';
    use File::Find::Rule;
    my @gdal_configs
      = File::Find::Rule->file()
                        ->name( 'gdal-config' )
                        ->in( '.' );
    my @pkg_configs
      = File::Find::Rule->file()
                        ->name( 'gdal.pc' )
                        ->in( '.' );
    say 'gdal-configs: ' . join ' ', @gdal_configs;
    say 'pkg-configs:  ' . join ' ', @pkg_configs;
    
    return if !@gdal_configs || !@pkg_configs;
    
    open my $gc_fh, '<', $gdal_configs[0] or die $!;
    my $dep_libs = '';
    while (defined (my $line = <$gc_fh>)) {
        if ($line =~ /CONFIG_DEP_LIBS=(.+)$/) {
            $dep_libs = $1;
            last;
        }
    }
    close $gc_fh;

    #  trim quotes (could do in prev check, but...)
    $dep_libs =~ s/^\"//;
    $dep_libs =~ s/\"$//;
    
    open my $pk_fh, '<', $pkg_configs[0] or die $!;
    my @pkg_conf;
    while (defined (my $line = <$pk_fh>)) {
        push @pkg_conf, $line;
    }
    close $pk_fh;

    #  change all (we should be more nuanced and do only the one that matters)
    foreach my $pkg_config_file (@pkg_configs) {
        say "Adding gdal dep_libs to $pkg_config_file";
        #  now add the dep libs to the pkg_conf file
        open $pk_fh, '>', $pkg_config_file or die $!;
        foreach my $line (@pkg_conf) {
            if ($line =~ /^CONFIG_INST_LIBS/) {
                chomp $line;
                $line .= " $dep_libs\n";
            }
            print {$pk_fh} $line;
        }
        close $pk_fh;
    }
}

sub get_gdal_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;
}


sub get_drivers_to_disable {
  #return;
  my @gdal_drivers = qw /
    jdem xpm zmap blx
    cals ceos coasp
    cosar ctg dimap elas
    fit gff gxf
    hf2 iris leveller
    msgn prf
    rmf rs2 sgi sigdem
    stacta terragen til rik
    ozi 
  /;
  my @ogr_drivers = qw /
    tiger edigeo wasp vdv
    geoconcept georss gmt
    jml 
  /;

  my @args;
  push @args, map {"-DGDAL_ENABLE_DRIVER_${_}_PLUGIN:BOOL=OFF"} map {uc} @gdal_drivers;
  push @args, map {"-DOGR_ENABLE_DRIVER_${_}_PLUGIN:BOOL=OFF"}  map {uc} @ogr_drivers;
  return wantarray ? @args : \@args;
}
