#
# Copyright 1999, 2000, 2001 Patrik Stridvall
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

package modules;

use strict;

use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;

@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK = qw($modules);

use vars qw($modules);

use config qw(
    &file_type &files_skip
    &file_directory
    &get_c_files &get_spec_files
    $current_dir $wine_dir
    $winapi_check_dir
);
use options qw($options);
use output qw($output);

sub import {
    $Exporter::ExportLevel++;
    &Exporter::import(@_);
    $Exporter::ExportLevel--;

    if (defined($modules)) {
	return;
    }

    $modules = 'modules'->new;
}

sub get_spec_file_type {
    my $file = shift;

    my $module;
    my $type;

    $module = $file;
    $module =~ s%^.*?([^/]+)\.spec$%$1%;

    open(IN, "< $file") || die "$file: $!\n";
    local $/ = "\n";
    my $header = 1;
    my $lookahead = 0;
    while($lookahead || defined($_ = <IN>)) {
	$lookahead = 0;
	s/^\s*(.*?)\s*$/$1/;
	s/^(.*?)\s*#.*$/$1/;
	/^$/ && next;

	if($header)  {
	    if(/^\d+|@/) { $header = 0; $lookahead = 1; }
	    next;
	}

	if(/^(\d+|@)\s+pascal(?:16)?/) {
	    $type = "win16";
	    last;
	}
    }
    close(IN);

    if(!defined($type)) {
	$type = "win32";
    }

    return ($type, $module);
}

sub new {
    my $proto = shift;
    my $class = ref($proto) || $proto;
    my $self  = {};
    bless ($self, $class);

    my $spec_file_found = $self->find_spec_files();
    $self->read_spec_files($spec_file_found);

    return $self;
}

sub find_spec_files {
    my $self = shift;

    my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
    my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};

    $output->progress("modules");

    my $spec_file_found = {};
    my $allowed_dir;
    my $spec_file;

    my @spec_files = <{dlls/*/*.spec,dlls/*/*/*.spec}>;

    foreach $spec_file (@spec_files) {
        $spec_file =~ /(.*)\/.*\.spec/;

        $allowed_dir = $1;

        $$spec_file_found{$spec_file}++;
        $$spec_file2dir{$spec_file}{$allowed_dir}++;
        $$dir2spec_file{$allowed_dir}{$spec_file}++;
    }

    return $spec_file_found;
}

sub read_spec_files {
    my $self = shift;
    
    my $spec_file_found = shift;

    my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
    my $spec_files16 = \@{$self->{SPEC_FILES16}};
    my $spec_files32 = \@{$self->{SPEC_FILES32}};
    my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
    my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};

    my @spec_files;
    if($wine_dir eq ".") {
	@spec_files = get_spec_files("winelib");
    } else {
	my %spec_files = ();
	foreach my $dir ($options->directories) {
	    $dir = "$current_dir/$dir";
	    $dir =~ s%/\.$%%;
	    foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
		$spec_files{$spec_file}++;
	    }
	}
	@spec_files = sort(keys(%spec_files));
    }

    @$spec_files16 = ();
    @$spec_files32 = ();
    foreach my $spec_file (@spec_files) {
	(my $type, my $module) = get_spec_file_type("$wine_dir/$spec_file");

	$$spec_file2module{$spec_file} = $module;
	$$module2spec_file{$module} = $spec_file;

	if($type eq "win16") {
	    push @$spec_files16, $spec_file;
	} elsif($type eq "win32") {
	    push @$spec_files32, $spec_file;
	} else {
	    $output->write("$spec_file: unknown type '$type'\n");
	}
    }

    foreach my $spec_file (@spec_files) {
	if(!$$spec_file_found{$spec_file} && $spec_file !~ m%tests/[^/]+$%) {
	    $output->write("modules: $spec_file: exists but is not specified\n");
	}
    }
}

sub all_modules {
    my $self = shift;

    my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};

    return sort(keys(%$module2spec_file));
}

sub complete_modules {
    my $self = shift;

    my $c_files = shift;

    my %dirs;

    foreach my $file (@$c_files) {
	my $dir = file_directory("$current_dir/$file");
	$dirs{$dir}++;
    }

    my @c_files = get_c_files("winelib");
    @c_files = files_skip(@c_files);
    foreach my $file (@c_files) {
	my $dir = file_directory($file);
	if(exists($dirs{$dir})) {
	    $dirs{$dir}--;
	}
    }

    my @complete_modules = ();
    foreach my $module ($self->all_modules) {
	my $index = -1;
	my @dirs = $self->allowed_dirs_for_module($module);
	foreach my $dir (@dirs) {
	    if(exists($dirs{$dir}) && $dirs{$dir} == 0) {
		$index++;
	    }
	}
	if($index == $#dirs) {
	    push @complete_modules, $module;
	}
    }

    return @complete_modules;
}

sub is_allowed_module {
    my $self = shift;

    my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};

    my $module = shift;

    return defined($$module2spec_file{$module});
}

sub is_allowed_module_in_file {
    my $self = shift;

    my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
    my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};

    my $module = shift;
    my $file = shift;
    $file =~ s/^\.\///;

    my $dir = $file;
    $dir =~ s/\/[^\/]*$//;

    if($dir =~ m%^include%) {
	return 1;
    }

    foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
	if($$spec_file2module{$spec_file} eq $module) {
	    return 1;
	}
    }

    return 0;
}

sub allowed_modules_in_file {
    my $self = shift;

    my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
    my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};

    my $file = shift;
    $file =~ s/^\.\///;

    my $dir = $file;
    $dir =~ s/\/[^\/]*$//;

    my %allowed_modules = ();
    foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
	my $module = $$spec_file2module{$spec_file};
	$allowed_modules{$module}++;
    }

    my $module = join(" & ", sort(keys(%allowed_modules)));

    return $module;
}

sub allowed_dirs_for_module {
   my $self = shift;

   my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
   my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};

   my $module = shift;

   my $spec_file = $$module2spec_file{$module};

   return sort(keys(%{$$spec_file2dir{$spec_file}}));
}

sub allowed_spec_files16 {
    my $self = shift;

    my $spec_files16 = \@{$self->{SPEC_FILES16}};

    return @$spec_files16;
}

sub allowed_spec_files32 {
    my $self = shift;

    my $spec_files32 = \@{$self->{SPEC_FILES32}};

    return @$spec_files32;
}

sub found_module_in_dir {
    my $self = shift;

    my $module = shift;
    my $dir = shift;

    my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};

    $dir = "$current_dir/$dir";
    $dir =~ s%/\.$%%;

    $$used_module_dirs{$module}{$dir}++;
}

sub global_report {
    my $self = shift;

    my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
    my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
    my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};

    my @messages;
    foreach my $dir ($options->directories) {
	$dir = "$current_dir/$dir";
	$dir =~ s%/\.$%%;
	foreach my $module ($self->all_modules) {
	    if(!$$used_module_dirs{$module}{$dir}) {
		my $spec_file = $$module2spec_file{$module};
		push @messages, "modules: $spec_file: directory ($dir) is not used\n";
	    }
	}
    }

    foreach my $message (sort(@messages)) {
	$output->write($message);
    }
}

1;
