<?php

declare(strict_types=1);
namespace Tests\git2;
use git2\git;
use git2\git_attr_check;
use git2\git_attr_options;
use git2\git_attr_value_t;

final class AttrTest extends GitTestCase
{

	public function testAddMacro(): void
	{
		$dir = $this->mkdir('add_macro');
		git::repository_init($repo, $dir, false);
		$this->assertOK(git::attr_add_macro($repo, 'binary', '-diff -crlf'));
	}

	public function testValue(): void
	{
		$dir = $this->mkdir('value');
		git::repository_init($repo, $dir, false);
		$this->assertSame(git_attr_value_t::STRING, git::attr_value('foo'));
	}

	public function testForeach(): void
	{
		$dir = $this->mkdir('foreach');
		git::repository_init($repo, $dir, false);
		file_put_contents($dir . '/.gitattributes', 'foo -text');

		git::attr_cache_flush($repo);

		$res = git::attr_foreach(
			$repo,
			git_attr_check::NO_SYSTEM,
			'foo',
			function(string $name, ?string $value): int {
				static $i = 0;
				$this->assertSame(0, $i++);
				$this->assertSame('text', $name);
				$this->assertSame('[internal]__FALSE__', $value); // Where does this come from?
				return 0;
			},
		);

		$this->assertOK($res);

		$opts = new git_attr_options;
		$opts->version = git_attr_options::VERSION;

		$res = git::attr_foreach_ext(
			$repo,
			$opts,
			'foo',
			function(string $name, ?string $value): int {
				static $i = 0;
				$this->assertSame(0, $i++);
				$this->assertSame('text', $name);
				$this->assertSame('[internal]__FALSE__', $value);
				return 0;
			},
		);

		$this->assertOK($res);
	}

	public function testOptions(): void
	{
		$opts = new git_attr_options;

		$this->assertSame(0, $opts->version);
		$this->assertSame(0, $opts->flags);
		$this->assertTrue(git::oid_is_zero($opts->attr_commit_id));

		git::oid_fromstr($oid, '0000000000000000000000000000000000000001');

		$opts->version        = git_attr_options::VERSION;
		$opts->flags          = git_attr_check::NO_SYSTEM | git_attr_check::INDEX_ONLY;
		$opts->attr_commit_id = $oid;

		$this->assertSame(git_attr_options::VERSION, $opts->version);
		$this->assertSame(git_attr_check::NO_SYSTEM | git_attr_check::INDEX_ONLY, $opts->flags);
		$this->assertSame('0000000000000000000000000000000000000001', git::oid_tostr_s($opts->attr_commit_id));
	}

	public function testGet(): void
	{
		$dir = $this->mkdir('get');
		git::repository_init($repo, $dir, false);
		file_put_contents($dir . '/.gitattributes', 'foo -text');

		$this->assertOK(git::attr_get($value, $repo, git_attr_check::NO_SYSTEM, 'foo', 'text'));
		$this->assertSame('[internal]__FALSE__', $value);

		$opts = new git_attr_options;
		$opts->version = git_attr_options::VERSION;

		$this->assertOK(git::attr_get_ext($value, $repo, $opts, 'foo', 'text'));
		$this->assertSame('[internal]__FALSE__', $value);
	}

	public function testGetMany(): void
	{
		$dir = $this->mkdir('get');
		git::repository_init($repo, $dir, false);
		file_put_contents($dir . '/.gitattributes', 'foo -text');

		$this->assertOK(git::attr_get_many($values, $repo, git_attr_check::NO_SYSTEM, 'foo', ['text', 'foo', 'text']));
		$this->assertSame(['[internal]__FALSE__', null, '[internal]__FALSE__'], $values);

		$opts = new git_attr_options;
		$opts->version = git_attr_options::VERSION;

		$this->assertOK(git::attr_get_many_ext($values, $repo, $opts, 'foo', ['text', 'foo', 'text']));
		$this->assertSame(['[internal]__FALSE__', null, '[internal]__FALSE__'], $values);
	}

}