<?php

declare(strict_types=1);
namespace Tests\git2;
use git2\git;
use git2\git_pathspec_flag_t;
use git2\git_pathspec_match_list;
use git2\git_strarray;

final class PathspecTest extends GitTestCase
{

	public function testMatchDiff(): void
	{
		git::diff_from_buffer($diff, file_get_contents(__DIR__ . '/fixtures/diff.foo.patch'));
		$this->assertOK(git::pathspec_new($ps, git_strarray::from(['foo'])));
		$this->assertOK(git::pathspec_match_diff($list, $diff, git_pathspec_flag_t::NO_MATCH_ERROR, $ps));
		$this->assertInstanceOf(git_pathspec_match_list::class, $list);
		$this->assertSame(1, git::pathspec_match_list_entrycount($list));

		$delta = git::pathspec_match_list_diff_entry($list, 0);
		$this->assertNotNull($delta);
	}

	public function testMatchIndex(): void
	{
		$dir = $this->mkdir('match_index');
		git::repository_init($repo, $dir, false);
		git::repository_index($index, $repo);

		touch($dir . '/foo');
		touch($dir . '/bar');

		git::index_add_bypath($index, 'foo');
		git::index_add_bypath($index, 'bar');

		$this->assertOK(git::pathspec_new($ps, git_strarray::from(['foo'])));
		$this->assertOK(git::pathspec_match_index($list, $index, git_pathspec_flag_t::NO_MATCH_ERROR, $ps));
		$this->assertInstanceOf(git_pathspec_match_list::class, $list);
		$this->assertSame(1, git::pathspec_match_list_entrycount($list));
		$this->assertSame('foo', git::pathspec_match_list_entry($list, 0));
	}

	public function testMatchTree(): void
	{
		$dir = $this->mkdir('match_tree');
		git::repository_init($repo, $dir, false);
		git::repository_index($index, $repo);
		touch($dir . '/foo');
		git::index_add_bypath($index, 'foo');
		git::index_write_tree($treeId, $index);
		git::tree_lookup($tree, $repo, $treeId);

		$this->assertOK(git::pathspec_new($ps, git_strarray::from(['foo'])));
		$this->assertOK(git::pathspec_match_tree($list, $tree, git_pathspec_flag_t::NO_MATCH_ERROR, $ps));
		$this->assertInstanceOf(git_pathspec_match_list::class, $list);
		$this->assertSame(1, git::pathspec_match_list_entrycount($list));
		$this->assertSame('foo', git::pathspec_match_list_entry($list, 0));
	}

	public function testMatchWorkdir(): void
	{
		$dir = $this->mkdir('match_tree');
		git::repository_init($repo, $dir, false);
		touch($dir . '/foo');
		$this->assertOK(git::pathspec_new($ps, git_strarray::from(['foo'])));
		$this->assertOK(git::pathspec_match_workdir($list, $repo, git_pathspec_flag_t::NO_MATCH_ERROR, $ps));
		$this->assertInstanceOf(git_pathspec_match_list::class, $list);
		$this->assertSame(1, git::pathspec_match_list_entrycount($list));
		$this->assertSame('foo', git::pathspec_match_list_entry($list, 0));
	}

	public function testMatchesPath(): void
	{
		$this->assertOK(git::pathspec_new($ps, git_strarray::from(['foo'])));
		$this->assertTrue(git::pathspec_matches_path($ps, git_pathspec_flag_t::DEFAULT, 'foo'));
		$this->assertFalse(git::pathspec_matches_path($ps, git_pathspec_flag_t::DEFAULT, 'bar'));
	}

	public function testFailed(): void
	{
		$dir = $this->mkdir('failed');
		git::repository_init($repo, $dir, false);
		git::repository_index($index, $repo);
		touch($dir . '/foo');
		git::index_add_bypath($index, 'foo');
		$this->assertOK(git::pathspec_new($ps, git_strarray::from(['foo', 'hello'])));
		$this->assertOK(git::pathspec_match_index($list, $index, git_pathspec_flag_t::FIND_FAILURES, $ps));
		$this->assertSame(1, git::pathspec_match_list_failed_entrycount($list));
		$this->assertSame('hello', git::pathspec_match_list_failed_entry($list, 0));
	}

}