#!/usr/bin/env perl

# Some tests for 'darcs pull' 

use lib 'lib/perl';
use Test::More 'no_plan';
use Test::Darcs;
use strict;
use warnings;
use Cwd;
use POSIX 'getuid';
use File::Slurp;
use File::Temp 'tempdir';

my $work_dir = tempdir( CLEANUP => 1 );
chdir $work_dir;


cleanup 'temp1';
cleanup 'temp2';
ok(mkpath('temp1'), "temp1 created");
ok(mkpath('temp2/one/two'), "temp2/one/two created");
ok(chdir('temp1'), "chdir temp1");
darcs 'init';
ok(chdir('../temp2'), "chdir ../temp2");
darcs 'init';
ok(chdir('one/two'), "chdir one/two");

{
    my $test_name = 'darcs pull should work relative to the current directory';
    my $pull_out = darcs 'pull -a ../../../temp1';
    like($pull_out, qr/No remote changes to pull in/i, $test_name);
}

{
    my $test_name = 'darcs pull should pull into repo specified with --repo';
    chdir '../../';  # now in temp2
    darcs 'add one';
    darcs q(record --patch-name 'uno' --all );
    chdir '../';     # now outside of any repo
    like(darcs('pull --repodir temp1 --all ../temp2'), # temp2 is relative to temp1
        qr/Finished pulling./i, $test_name);
}

TAKE_LOCK: {
    # set up server repo
    `date >>temp2/one/date.t`;
    darcs 'add --repodir ./temp2 one/date.t';
    darcs q(record --repodir ./temp2 -a -m 'foo');

    # set up client repo for failure
   chmod 0555,'./temp1/one/'; # remove read permissions
    my $out = darcs 'pull --repodir ./temp1 -a';
    rmtree('./temp1/one/');
    if ($^O =~ /msys/i) {
        pass('this test fails on windows, so ignore it');
    } else {
      if(getuid() == 0) {
        pass("root never gets permission denied");
      } else {
        like($out, qr#one/date\.t.+: permission denied#i,
             'expect permission denied error');
      }
    }
};


SELF_PULL: {
    chdir './temp1'; 

    my $default_repo_pre_test = 'Before trying to pull from self, defaultrepo is something else';
    open(DEFAULT_REPO,'<./_darcs/prefs/defaultrepo') || die "Couldn't open defaultrepo";
    my $default_repo = (<DEFAULT_REPO>);
    close(DEFAULT_REPO);

    unlike($default_repo,qr/temp1/,$default_repo_pre_test);

    my $test_name = 'return special message when you try to pull from yourself';
    my $abs_path = cwd();
    like(darcs(qq(pull -a $abs_path)), qr/Can.t pull from current repository!/i, $test_name);
    like(darcs('pull -a .'), qr/Can.t pull from current repository!/i, $test_name);

    my $set_default_repo_test = "and do not update the default repo to be the current dir";
    open(DEFAULT_REPO,'<./_darcs/prefs/defaultrepo') || die "Could not open defaultrepo";
    my $new_default_repo = (<DEFAULT_REPO>);
    close(DEFAULT_REPO);

    unlike($new_default_repo,qr/temp1/,$set_default_repo_test);

    cleanup('_darcs/prefs/defaultrepo');
    like(darcs('pull'), qr/please specify one/i, $test_name);
    write_file('_darcs/prefs/defaultrepo','.');
    like(darcs('pull'), qr/Can.t pull from current repository!/i, '[issue358] '.$test_name);
    unlike(darcs('pull ../*'), qr/Can.t pull from current repository!/i, '[issue427] '.$test_name);

    chdir '../';     # now outside of any repo
}

ROLLBACK_PULL: {
    use File::Path;
    chdir 'temp1';
    write_file 'foo','a';
    darcs 'record -lam AA ';
    write_file 'foo','b';
    darcs 'record  -lam BB ';
    write_file 'foo','c';
    darcs 'record  -lam CC ';
    like(echo_to_darcs("rollback -p CC -a -m unC ",""), qr/Finished rolling back/);
    chdir '../';
    rmtree 'temp2/';
    darcs 'get --to-patch B temp1 temp2';
    chdir 'temp2';
    system "sleep 1"; # So that rollback won't have same timestamp as get.
    like(echo_to_darcs("rollback -p BB -a -m unB ",""), qr/Finished rolling back/);
    darcs 'revert -a';
    my $pull_out = darcs 'pull -a ../temp1';
    unlike($pull_out,qr/Error applying patch/i,
           'pull after rollback avoids failure');
    chdir '../';
};

NONEWLINES_PULL: {
  chdir 'temp1';
  `echo -n foo > baz`;
  darcs 'add baz';
  darcs 'record  -am newbaz ';
  chdir '../temp2';
  like(darcs('pull -a'), qr/Finished pulling/, 'pull of newlineless patch');
  `echo -n bar > baz`;
  darcs 'record  -am bazbar ';
  chdir '../temp1';
  like(darcs('pull ../temp2 -a'), qr/Finished pulling/,
       'pull of newlineless patch');
  `echo -n bar > correct_baz`;
  ok(!(system "diff baz correct_baz"), 'pull was right');
  chdir '..';
}

CREATE_DIR_ERROR: {
   my $test_name = "when a patch creating a directory is attempted to be applied
       while a directory with that name already exists, a warning is raised, but
       the pull succeeds.";
   mkdir 'temp1/newdir';
   ok((chdir 'temp1/'), "chdir succeeds");;
   darcs 'add newdir';
   darcs 'record  -am newdir ';
   ok((chdir '../temp2'), "chdir succeeds");;
   mkdir 'newdir';
   my $out = darcs('pull -a ../temp1');
   like($out, qr/Backing/i, $test_name);
   like($out, qr/Finished pulling/i, $test_name);
   like($out, qr/newdir/i, "...and report the name of the directory involved");
   ok((chdir '../'), "chdir succeeds");;
}

chdir '../'; # move out of tmp dir, so it can be auto-removed. 

