#!/usr/local/bin/perl -w

=head1 NAME

p4.t - testing of vcp p4 i/o

=cut

use strict ;

use Carp ;
use File::Spec ;
use POSIX ':sys_wait_h' ;
use Test ;
use VCP::TestUtils ;

my @vcp = vcp_cmd ;

my $t = -d 't' ? 't/' : '' ;

my $p4_options ;
my $p4_spec_base ;
my $p4_rev_root ;
my $p4_spec ;

# what change number to start incremental export at
my $first_import_1_change; # was called $incr_change

my $cvs_options ;
my $cvs_module ;

my $cvs_borken = $ENV{CVSBORKEN} || cvs_borken;



my @tests = (

sub {
   return skip $cvs_borken, "" if $cvs_borken ;
   # init_cvs before initting p4d, since it may need to set the uid and euid.
   $cvs_module = 'p4_t_module' ;
   $cvs_options = init_cvsroot "p4_", $cvs_module ;
   ok 1 ;
},




###
# start p4 daemon in existing p4root_0
sub {
   $ENV{P4USER}   = "foobar_user" ;
   $ENV{P4PORT}   = "foobar_port" ;
   $ENV{P4CLIENT} = "foobar_client" ;
   $ENV{P4PASSWD} = "foobar_passwd" ;

   $p4_options = launch_p4d "p4_", { 
      repo_dir    => "${t}p4root_0",
   } ;
   $p4_spec_base = "p4:$p4_options->{user}:\@$p4_options->{port}:" ;
   $p4_rev_root = "//depot/foo/" ;
   $p4_spec = "$p4_spec_base$p4_rev_root" ;
   ok 1 ;
},



##
## p4->cvs->revml bootstrap
##
sub { ## Two ok's in next test.
   return skip $cvs_borken, "" if $cvs_borken ;
},

sub {
   return skip $cvs_borken, "" if $cvs_borken ;

   $ENV{CVSROOT} = $cvs_options->{repo};

   eval {
      run [ @vcp, "${p4_spec}...", "cvs:$cvs_module/" ], \undef;

      ok 1 ;

      my $infile  = $t . "test-p4-in-0.revml" ;
      my $in = slurp $infile ;
      my $out = get_vcp_output "cvs:$cvs_module/", qw( -r 1.1: ) ;

      s_content  qw( rep_desc rep_type time user_id ), \$in, \$out ;
      s_content  qw( rev_root ),                       \$in, $cvs_module ;
      rm_elts    qw( p4_info change_id ),              \$in ;
      rm_elts    qw( label ), qr/r_\w+|ch_\w+/,        \$in, \$out ;

      $out =~ s{<rev_id>1.}{<rev_id>}g ;
      $out =~ s{<base_rev_id>1.}{<base_rev_id>}g ;
      $out =~ s{((id="|_id>)?[^>]*#)1\.}{$1}g;

      $in =~ s{(id="|_id>)/+ignored}{$1/$cvs_module}g;

      assert_eq $infile, $in, $out ;
   } ;
   ok (( $@ || '' ), '', 'diff' );
},



# determine next change number that p4d will use this will become the
# change number of the first change in t/test-p4-in-1.revml when it is
# imported.
sub {
   # get counter change
   run_p4 [ qw( counter change ) ],
      \undef,
      \$first_import_1_change,
      $p4_options ;

   chomp $first_import_1_change ;
   die "Invalid change counter value: '$first_import_1_change'"
      unless $first_import_1_change =~ /^\d+$/ ;

   ++$first_import_1_change ;

   ok 1;
},



# shut down the p4root_0 p4d
sub {
   $p4_options->{p4d_handle}->kill_kill;
   ok 1;
},


###
# start p4d in existing p4root_1
sub {
   $ENV{P4USER}   = "foobar_user" ;
   $ENV{P4PORT}   = "foobar_port" ;
   $ENV{P4CLIENT} = "foobar_client" ;
   $ENV{P4PASSWD} = "foobar_passwd" ;

   $p4_options = launch_p4d "p4_", { 
      repo_dir      => "${t}p4root_1",
   } ;
   $p4_spec_base = "p4:$p4_options->{user}:\@$p4_options->{port}:" ;
   $p4_spec = "$p4_spec_base$p4_rev_root" ;
   ok 1 ;
},




##
## p4->cvs->revml incremental export
##
sub { ## Two ok's in next test.
   return skip $cvs_borken, "" if $cvs_borken ;
},

sub {
   return skip $cvs_borken, "" if $cvs_borken ;

   $ENV{CVSROOT} = $cvs_options->{repo};

   eval {
      run [ @vcp, "${p4_spec}...\@$first_import_1_change,#head", "cvs:$cvs_module/" ], \undef;

      ok 1 ;

      my $infile  = $t . "test-p4-in-1.revml" ;
      my $in = slurp $infile ;
      my $out = get_vcp_output "cvs:$cvs_module/", "-r", "ch_$first_import_1_change:" ;

      s_content  qw( rep_desc rep_type time user_id ), \$in, \$out ;
      s_content  qw( rev_root ),                       \$in, $cvs_module ;
      rm_elts    qw( p4_info change_id ),              \$in ;
      rm_elts    qw( label ), qr/r_\w+|ch_\w+/,        \$in, \$out ;

      $out =~ s{<rev_id>1.}{<rev_id>}g ;
      $out =~ s{<base_rev_id>1.}{<base_rev_id>}g ;
      $out =~ s{((id="|_id>)?[^>]*#)1\.}{$1}g;

      $in =~ s{(id="|_id>)/+ignored}{$1/$cvs_module}g;

      rm_elts    qw( branches ),                      \$in ;

      ## TODO: This is an incremental export and perforce does not give us
      ## a trivial way to figure out what branch a file is on (since
      ## multiple branch views can cover the same file), so we bail
      ## on that for now.
      rm_elts    qw( branch_id ),                     \$in ;

      assert_eq $infile, $in, $out ;
   } ;
   ok $@ || '', '', 'diff' ;
},

# shut down the p4root_1 p4d
sub {
   $p4_options->{p4d_handle}->kill_kill;
   ok 1;
},


);  # end @tests.



plan tests => scalar @tests, todo => [ 4 ] ;

my $p4d_borken = p4d_borken ;

my $why_skip ;
$why_skip .= "p4 command not found\n"  unless ( `p4 -V`  || 0 ) =~ /^Perforce/ ;
$why_skip .= "$p4d_borken\n"           if $p4d_borken ;



$why_skip ? skip( $why_skip, '' ) : $_->() for @tests ;
