#!/usr/bin/perl
use strict;
use warnings;
use Carp;
use FindBin;
use Getopt::Long;
use lib "$FindBin::Bin/../lib/perl";
use PDB::Entry;
use STAMP::Domain;
use STAMP::Tools;

if ( !$ENV{STAMPDIR} ) {
	croak "error: environment variable STAMPDIR must be specified\n";
}

my $pdbcodes;
my $domain_file;
my $list;

GetOptions(
	"domain-file=s" => \$domain_file,
	"list" => \$list,
	"pdb=s"         => \$pdbcodes,
);

my @descriptors;
if ($pdbcodes) {
	my @pdbcodes = split /,/, $pdbcodes;

	for my $pdbid ($pdbcodes) {
        my $id = substr($pdbid,0,4);
		my $pdbfile = getfile($pdbid)
			or croak "cannot find PDB file for $pdbid";

		my $pdb = PDB::Entry->new($pdbfile);
		for my $chain ( sort keys %{ $pdb->chains } ) {
			my $desc = "$pdbfile $id$chain { CHAIN $chain }\n";
			my $domain_ok = 1;
			for my $residue ( @{ $pdb->chains->{$chain} } ) {
				if ( $residue->is_amino && !$residue->atom('CA') ) {
					my $to_str = $residue->to_string;
					warn <<"WARNING";
% WARNING Residue $to_str in chain $chain of $pdbfile is missing its mainchain CA atom. 
% STAMP cannot use this chain. 
WARNING
					$domain_ok = 0;
				}
			}
			if ($domain_ok) {
				push @descriptors, $desc;
			}
		}
	}
}

if ($domain_file) {
	open my $IN, '<', $domain_file or croak "$!: $domain_file";
	while ( my $line = <$IN> ) {
        chomp $line;
		next if $line =~ /^%/;
		my $domain  = STAMP::Domain->new($line);
		my $pdbfile = getfile( $domain->pdb );
		if ( !$pdbfile ) {
			croak "Cannot find PDB file for domain descriptor $line";
		}
		my $desc;
		eval { $desc = STAMP::Tools::descriptor_ok( $domain, $pdbfile ); };
		if ($desc) {
			push @descriptors, "$desc\n";
		}
		else {
            my $error = (split q/\n/,$@)[0];
			die <<"ERROR";
% Error in descriptor: $line
$error
ERROR
            ;
		}
	}
}

if ($list){
    print @descriptors;
}

sub getfile {
	my ( $pdbid, $type ) = @_;
    $type = 'pdb' unless defined $type;
	my $dirfile = "$ENV{STAMPDIR}/$type.directories";

	my $file;
	open my $FH, '<', $dirfile or croak "$!: $dirfile";
	while (<$FH>) {
		my ( $path, $prefix, $suffix ) = map { $_ eq '_' ? q{} : $_ } split;
		if ($path) {
			$path .= '/';
		}
		$file = "$path$prefix$pdbid$suffix";
		if ( -e $file ) {
			last;
		}
		undef $file;
	}
	close $FH;
	return $file;
}
