#!/usr/bin/perl -w

# Syntax: $0 path/to/Build.PL

use warnings;
use strict;
use File::Slurp;
use re 'eval';
use Regexp::Common qw(delimited balanced number);

# Helper function to shortcut creating regexp for hash key
sub key
{
   my $word = shift;
   return qr/(?:$word|\"$word\"|\'$word\')/xms;
}

### BEGIN build regexp pieces ###

my $s = qr/(?: \s | \# [^\r\n]* )/xms;
my $comma = qr/ \s* (?: => | , ) \s* /xms;
my $number = qr/[\d_\.]+/xms; # simplistic, includes version numbers
my $scalar = qr/( undef | $number | $RE{delimited}{-delim=>q{'"}})/xms;
my $array = qr/ $RE{balanced}{-parens=>'[]'} /xms;
my $hash = qr/ $RE{balanced}{-parens=>'{}'} /xms;

my $sharpbang = qr/\#!\S+[^\r\n]*/xms;
my $mb_include = qr/use \s+ Module::Build (?:\s+ $number)? \s*;/xms;
# A few otherwise-simple modules include 'use File::Spec::Functions;' for no reason I can understand
my $misc_pragma = qr/use \s+ (?:warnings|strict|File::Spec::Functions) \s*;/xms;

my $module_name = key('module_name').$comma.$scalar;
my $dist_name = key('dist_name').$comma.$scalar;
my $dist_version_from = key('dist_version_from').$comma.$scalar;
my $dist_version = key('dist_version').$comma.$scalar;
my $installdirs = key('installdirs').$comma.$scalar;
my $script_files = key('script_files').$comma.$array;
my $requires = key('requires').$comma.$hash;
my $build_requires = key('build_requires').$comma.$hash;
my $license = key('license').$comma.$scalar;
my $dist_abstract = key('dist_abstract').$comma.$scalar;
my $recommends = key('recommends').$comma.$hash;
my $dist_author = key('dist_author').$comma.$scalar;
my $sign = key('sign').$comma.$scalar;
my $add_to_cleanup = key('add_to_cleanup').$comma.$array;
my $create_makefile_pl = key('create_makefile_pl').$comma.$scalar;
my $create_readme = key('create_readme').$comma.$scalar;

my $known_keyval = qr/(?: $module_name|$dist_name|$dist_version_from|$dist_version|
                          $installdirs|$script_files|$requires|$build_requires )/xms;
my $ignorable_keyval = qr/(?: $license|$dist_abstract|$recommends|$dist_author|
                              $sign|$add_to_cleanup|$create_makefile_pl|
                              $create_readme )/xms;
my $keyval = qr/(?: $known_keyval | $ignorable_keyval )/xms;

my $declaration = qr/(?: (?:$keyval) $s* (?:,$s*)? )*/xms;
my $instantiation = qr/(?: Module::Build $s* -> $s* new | new $s* Module::Build ) $s* \( $s* $declaration $s* \)/xms;
my $outputcmd = qr/create_build_script (?: \s* \( \s* \) )? /xms;
my $direct_output = qr/$instantiation $s* -> $s* $outputcmd/xms;
my $object_output = qr/(?:my \s*)? \$\w+ $s* = $s* $instantiation \s*; $s* \$\w+ $s* -> $s* $outputcmd/xms;
my $output = qr/(?: $direct_output | $object_output ) (?:$s* ;)?/xms;
my $termination = qr/(?: exit .* | __END__ .* )/xms;

my $simple = qr/
   \A
   (?:$sharpbang \s+)? $s*
   (?: $misc_pragma $s*)*
   $mb_include $s*
   (?: $misc_pragma $s*)*
   $output $s*
   $termination?
   \z
/xms;

#    (?:my \s*)? \$\w+ $s* = $s* new $s* Module::Build $s* \( $declaration

### END build regexp pieces ###


for my $file (@ARGV)
{
   my $content = read_file($file);
   print $content =~ m/$simple/xms ? "simple  $file\n" : "complex $file\n";
   #print $&;  # for debugging
}
