use strict;
use File::Basename;

sub scan_fits_files {
	my $rawFiles        = shift(@_);
	my $fitsheaderRef   = shift(@_);
	my $doKmosFitsCheck = shift(@_);
	my %rec;

#	print "Exploring files $rawFiles\n";

#   check if there are any raw files
	my $fn = readpipe("ls $rawFiles 2>/dev/null");
	if (length($fn) == 0) {
		return %rec;
	}

	my @acceptedFiles = checkForKmosFitsStructure($rawFiles)
	  if $doKmosFitsCheck;

#	print "Read FITS header of files\n";

	my @keywords = ();
	foreach my $name ( keys %$fitsheaderRef ) {
		push @keywords, $$fitsheaderRef{$name}{path}
		  if $$fitsheaderRef{$name}{path} ne "";
	}

	my $cmd = "dfits $rawFiles | fitsort -d " . join( " ", @keywords );
#	print $cmd . "\n";
	open( my $DFITS, "-|", $cmd );

	my @fields;
	while (<$DFITS>) {
		chop;
		@fields = split /\t/, $_;
		foreach (@fields) { s/(.*?)\s+$/$1/; }
		my $file = $fields[0];

		#file had to pass previous check
		next if $doKmosFitsCheck && !scalar grep /^${file}$/, @acceptedFiles;

		foreach my $name ( keys %$fitsheaderRef ) {
			next if $$fitsheaderRef{$name}{path} eq "";
			my $ix =
			  fitskeyword_index( $$fitsheaderRef{$name}{path}, @keywords );
			$rec{$file}{$name} = $fields[$ix];
			lmax( \$$fitsheaderRef{$name}{maxLength}, $fields[$ix] );
		}
		$rec{$file}{filename} = basename( $file, "" );
		lmax( \$$fitsheaderRef{filename}{maxLength}, $rec{$file}{filename} );
		if ( defined $$fitsheaderRef{lamps} ) {
			my $lamps = '';
			$lamps .= "Ar,"  if $rec{$file}{lamp1} eq "T";
			$lamps .= "Ne,"  if $rec{$file}{lamp2} eq "T";
			$lamps .= "FF1," if $rec{$file}{lamp3} eq "T";
			$lamps .= "FF2," if $rec{$file}{lamp4} eq "T";

			if ( length($lamps) eq 0 ) {
				$lamps = "none";
			}
			else {
				$lamps = substr $lamps, 0, -1;    #skip last comma
			}
			$rec{$file}{lamps} = $lamps;
			lmax( \$$fitsheaderRef{lamps}{maxLength}, $rec{$file}{lamps} );
		}
	}
	close $DFITS;

	return %rec;
}

sub checkForKmosFitsStructure {
	my $files = shift(@_);
	print "Check proper FITS structure for raw KMOS detector files\n";

	my @keywords = qw(NAXIS NAXIS1 NAXIS2 EXTNAME
	  ins.filt1.name ins.filt2.name ins.filt3.name
	  ins.grat1.name ins.grat2.name ins.grat3.name
	);
	my $cmd = "dfits -x 0 $files | fitsort -d " . join( " ", @keywords );
	print $cmd . "\n";
	open( my $DFITS, "-|", $cmd );
	my @skippedFiles  = ();
	my @acceptedFiles = ();
	my ( @fields, @ext1, @ext2, @ext3 );

	while (<$DFITS>) {
		chop;
	  PARSE_PRIMARY_EXTENSION:
		@fields = split /\t/, $_;
		foreach (@fields) { s/(.*?)\s+$/$1/; }
		my $file = $fields[0];
		if ( length($file) < 2 ) {
			next;
		}    # something went wrong expect filename with more than 1 character

	 # read three extension records, numbered 1..3
	 # if less extensions found, parse current record again as primary extension
	 #	$ext1_line=""; $ext2_line=""; $ext3_line="";
		@ext1 = ();
		@ext2 = ();
		@ext3 = ();
		if ( !( $_ = <$DFITS> ) ) { last; }
		chop $_;
		@ext1 = split /\t/, $_;
		foreach (@ext1) { s/(.*?)\s+$/$1/; }

		if ( $ext1[0] != 1 ) {
			push @skippedFiles, "$file --- missing extensions (has none)";
			goto PARSE_PRIMARY_EXTENSION;
		}
		if ( !( $_ = <$DFITS> ) ) { last; }
		chop $_;
		@ext2 = split /\t/, $_;
		foreach (@ext2) { s/(.*?)\s+$/$1/; }
		if ( $ext2[0] != 2 ) {
			push @skippedFiles, "$file --- missing extensions (has only one)";
			goto PARSE_PRIMARY_EXTENSION;
		}
		if ( !( $_ = <$DFITS> ) ) { last; }
		chop $_;
		@ext3 = split /\t/, $_;
		foreach (@ext3) { s/(.*?)\s+$/$1/; }
		if ( $ext3[0] != 3 ) {
			push @skippedFiles, "$file --- missing extensions (has only two)";
			goto PARSE_PRIMARY_EXTENSION;
		}

		my $ix = fitskeyword_index( "NAXIS", @keywords );
		if ( $ext1[$ix] != 2 || $ext2[$ix] != 2 || $ext3[$ix] != 2 ) {
			push @skippedFiles,
			  "$file --- wrong number of dimensions, must be 2";
			push @skippedFiles,
			    join( " ", @ext1[ 0 .. 4 ] ) . "\n"
			  . join( " ", @ext2[ 0 .. 4 ] ) . "\n"
			  . join( " ", @ext3[ 0 .. 4 ] );
			next;
		}
		my $ix1 = fitskeyword_index( "NAXIS1", @keywords );
		my $ix2 = fitskeyword_index( "NAXIS2", @keywords );
		if (   $ext1[$ix1] != 2048
			|| $ext2[$ix1] != 2048
			|| $ext3[$ix1] != 2048
			|| $ext1[$ix2] != 2048
			|| $ext2[$ix2] != 2048
			|| $ext3[$ix2] != 2048 )
		{
			push @skippedFiles, "$file --- wrong image size, must be 2048x2048";
			push @skippedFiles,
			    join( " ", @ext1[ 0 .. 4 ] ) . "\n"
			  . join( " ", @ext2[ 0 .. 4 ] ) . "\n"
			  . join( " ", @ext3[ 0 .. 4 ] );
			next;
		}
		$ix = fitskeyword_index( "EXTNAME", @keywords );
		if (   $ext1[$ix] ne 'CHIP1.INT1'
			|| $ext2[$ix] ne 'CHIP2.INT1'
			|| $ext3[$ix] ne 'CHIP3.INT1' )
		{
			push @skippedFiles, "$file --- wrong extension name";
			push @skippedFiles,
			    join( " ", @ext1[ 0 .. 4 ] ) . "\n"
			  . join( " ", @ext2[ 0 .. 4 ] ) . "\n"
			  . join( " ", @ext3[ 0 .. 4 ] );
			next;
		}

		$ix1 = fitskeyword_index( "ins.filt1.name", @keywords );
		$ix2 = fitskeyword_index( "ins.filt2.name", @keywords );
		my $ix3 = fitskeyword_index( "ins.filt3.name", @keywords );
		if ( $fields[$ix1] ne $fields[$ix2] || $fields[$ix1] ne $fields[$ix3] )
		{
			push @skippedFiles, "$file --- different filter bands";
			push @skippedFiles, "-$fields[$ix1]- -$fields[$ix2]- -$fields[$ix3]-";
			next;
		}
		$ix1 = fitskeyword_index( "ins.grat1.name", @keywords );
		$ix2 = fitskeyword_index( "ins.grat2.name", @keywords );
		$ix3 = fitskeyword_index( "ins.grat3.name", @keywords );
		if ( $fields[$ix1] ne $fields[$ix2] || $fields[$ix1] ne $fields[$ix3] )
		{
			push @skippedFiles, "$file --- different grating bands";
			push @skippedFiles, "-$fields[$ix1]- -$fields[$ix2]- -$fields[$ix3]-";
			next;
		}
		$ix1 = fitskeyword_index( "ins.filt1.name", @keywords );
		$ix2 = fitskeyword_index( "ins.grat1.name", @keywords );
		if ( $fields[$ix1] ne "Block" ) {
			if ( $fields[$ix1] ne $fields[$ix2] ) {
				push @skippedFiles,
				  "$file --- filter and grating band don't match";
				push @skippedFiles, "-$fields[$ix1]- -$fields[$ix2]-";
				next;
			}
		}

		push @acceptedFiles, $file;
	}
	close $DFITS;
	print join("\n",@skippedFiles),"\n" if $#skippedFiles ne -1;
	return @acceptedFiles;
}

sub fitskeyword_index {
	my $pat   = shift(@_);
	my @arr   = @_;
	my $found = -1;
	for ( my $i = 0 ; $i <= $#arr ; $i++ ) {
		$found = $i if ( $arr[$i] eq $pat );
	}
	return $found + 1;
}

sub lmax {
	my $len    = shift(@_);
	my $string = shift(@_);
	my $slen   = length($string);
	return if $slen <= $$len;
	$$len = $slen;
}
return 1;
