use 5.008_007;
use ExtUtils::MakeMaker;

use strict;
use warnings;
use Config;
use Getopt::Long;
use FindBin;
use lib "$FindBin::Bin/lib";
use Getopt::Long 'GetOptions';

use SPVM::Builder::Util;

# If you edit yacc/spvm_yacc.y, spvm_yacc.c must be re-generated by the following command before "perl Makefile.PL"
#   yacc/bison.sh

# Check supported environment
{
  # SPVM only support 64bit integer Perl
  my $ivsize = $Config{ivsize};
  if ($ivsize < 8) {
    warn "SPVM don't support the Perl which \"ivsize\" is lower than 8\n";
    die "OS unsupported\n";
  }

  # SPVM only support NetBSD 7+
  if ($Config{osname} eq 'netbsd' && $Config{osvers} < 7) {
    warn "SPVM don't support NetBSD 6, 5, 4, 3, 2, 1";
    die "OS unsupported\n";
  }

  # Not support Alpine Linux because Alpine Linux tests fail in current SPVM
  if ($Config{myuname} =~ /alpine/i) {
    warn "Not support Alpine Linux because Alpine Linux tests fail in current SPVM";
    die "OS unsupported\n";
  }
  
  # old FreeBSD don't support some C99 complex functions
  if ($Config{osname} eq 'freebsd' && $Config{osvers} < 11.4) {
    warn "SPVM don't support NetBSD before version 11.4";
    die "OS unsupported\n";
  }
}

my @defines;
my $optimize;

GetOptions(
  "--DEFINE=s" => \@defines,
  "--OPTIMIZE=s" => \$optimize,
);

# Macro
@defines = map { "-D$_" } @defines;

# OPTIMIZE
unless ($optimize) {
  $optimize = '-O3';
}

# CCFLAGS
my $ccflags = $Config{ccflags};
$ccflags .= ' -std=c99';
# I want to print warnings, but if gcc version is different, can't suppress no needed warning message.
# so I dicide not to print warning in release version
if ($ENV{SPVM_TEST_ENABLE_WARNINGS}) {
  $ccflags .= ' -Wall -Wextra -Wno-unused-label -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wno-unused-variable -Wno-missing-field-initializers';
}

# INC
my $inc = '-Ilib/SPVM/Builder/include';

my @csource_files = ('SPVM.c', glob 'lib/SPVM/Builder/src/*.c');

WriteMakefile(
    NAME              => 'SPVM',
    VERSION_FROM      => 'lib/SPVM.pm', # finds $VERSION
    PREREQ_PM         => {}, # e.g., Module::Name => 1.1
    LICENSE           => 'perl_5',
    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM  => 'lib/SPVM.pm', # retrieve abstract from module
       AUTHOR         => 'Yuki Kimoto<kimoto.yuki@gmail.com>') : ()),
    CCFLAGS => $ccflags,
    OPTIMIZE => $optimize,
    C => [@csource_files],
    OBJECT            => '$(O_FILES)', # link all the C files too
    INC => $inc,
    test => {TESTS => 't/*.t t/*/*.t t/*/*/*.t'},
    clean => {FILES => "SPVM.o lib/SPVM/Builder/src/*.o .spvm_build t/default/.spvm_build t/precompile t/test_files_tmp "},
    DEFINE => "@defines -o \$@",
    META_MERGE => {
        'meta-spec' => { version => 2 },
        resources => {
            repository => {
                type => 'git',
                url  => 'https://github.com/yuki-kimoto/SPVM.git',
                web  => 'https://github.com/yuki-kimoto/SPVM',
            },
        },
    },
);

# Create precompile test
my $create_precompile_test_cmd = 'perl t/copy_default_to_precompile.pl';
system($create_precompile_test_cmd) == 0
  or die "Can't execute $create_precompile_test_cmd: $!";

# Add Build shared library make rule
sub MY::postamble {

  my $make_rule = '';
  
  unless (grep { $_ eq '-DSPVM_DONT_COMPILE_CORE_MODULES' } @defines) {
    # Native compile make rule
    $make_rule .= SPVM::Builder::Util::create_make_rule_native('SPVM::Util');
    $make_rule .= SPVM::Builder::Util::create_make_rule_native('SPVM::Math');
    $make_rule .= SPVM::Builder::Util::create_make_rule_native('SPVM::Hash');
    $make_rule .= SPVM::Builder::Util::create_make_rule_native('SPVM::Time');
    $make_rule .= SPVM::Builder::Util::create_make_rule_native('SPVM::Unicode');
    $make_rule .= SPVM::Builder::Util::create_make_rule_native('SPVM::Sort');
    $make_rule .= SPVM::Builder::Util::create_make_rule_native('SPVM::IO::Stdout');
    $make_rule .= SPVM::Builder::Util::create_make_rule_native('SPVM::IO::Stderr');
    
    # Precompile make rule
    $make_rule .= SPVM::Builder::Util::create_make_rule_precompile('SPVM::Util');
    $make_rule .= SPVM::Builder::Util::create_make_rule_precompile('SPVM::Sort');
    $make_rule .= SPVM::Builder::Util::create_make_rule_precompile('SPVM::Regex');
    $make_rule .= SPVM::Builder::Util::create_make_rule_precompile('SPVM::Unicode');
    $make_rule .= SPVM::Builder::Util::create_make_rule_precompile('SPVM::Hash');
  }
  
  return $make_rule;
}

1;
