<?php

declare(strict_types=1);
namespace Tests\git2;
use git2\git;
use git2\git_branch_iterator;
use git2\git_branch_t;
use git2\git_error_code;
use git2\git_reference;

final class BranchTest extends GitTestCase
{

	public function testCreate(): void
	{
		$dir = $this->mkdir('create');
		git::repository_init($repo, $dir, false);
		git::repository_index($index, $repo);
		git::index_write_tree($treeId, $index);
		git::tree_lookup($tree, $repo, $treeId);
		git::signature_now($sig, 'Jane Doe', 'jane.doe@example.com');
		git::commit_create_v($id, $repo, 'HEAD', $sig, $sig, null, 'Hello world!', $tree);
		git::commit_lookup($commit, $repo, $id);
		$this->assertOK(git::branch_create($ref, $repo, 'foo', $commit, false));
		$this->assertSame('refs/heads/foo', git::reference_name($ref));
		$this->assertOK(git::branch_name($name, $ref));
		$this->assertSame('foo', $name);
	}

	public function testLookup(): void
	{
		$dir = $this->mkdir('checked_and_head');
		git::repository_init($repo, $dir, false);
		git::repository_index($index, $repo);
		git::index_write_tree($treeId, $index);
		git::tree_lookup($tree, $repo, $treeId);
		git::signature_now($sig, 'Jane Doe', 'jane.doe@example.com');
		git::commit_create_v($id, $repo, 'HEAD', $sig, $sig, null, 'Hello world!', $tree);
		git::commit_lookup($commit, $repo, $id);
		$this->assertOK(git::branch_lookup($ref, $repo, 'master', git_branch_t::LOCAL));
		$this->assertInstanceOf(git_reference::class, $ref);
		$this->assertTrue(git::branch_is_checked_out($ref));
		$this->assertTrue(git::branch_is_head($ref));
	}

	public function testDelete(): void
	{
		$dir = $this->mkdir('delete');
		git::repository_init($repo, $dir, false);
		git::repository_index($index, $repo);
		git::index_write_tree($treeId, $index);
		git::tree_lookup($tree, $repo, $treeId);
		git::signature_now($sig, 'Jane Doe', 'jane.doe@example.com');
		git::commit_create_v($id, $repo, 'HEAD', $sig, $sig, null, 'Hello world!', $tree);
		git::commit_lookup($commit, $repo, $id);
		git::branch_create($ref, $repo, 'foo', $commit, false);
		$this->assertOK(git::branch_delete($ref));
		$this->assertSame(git_error_code::ENOTFOUND, git::branch_delete($ref));
	}

	public function testNameIsValid(): void
	{
		$this->assertOK(git::branch_name_is_valid($valid, 'foo'));
		$this->assertTrue($valid);
		$this->assertOK(git::branch_name_is_valid($valid, ''));
		$this->assertFalse($valid);
	}

	public function testIterator(): void
	{
		$dir = $this->mkdir('iterator');
		git::repository_init($repo, $dir, false);
		git::repository_index($index, $repo);
		git::index_write_tree($treeId, $index);
		git::tree_lookup($tree, $repo, $treeId);
		git::signature_now($sig, 'Jane Doe', 'jane.doe@example.com');
		git::commit_create_v($id, $repo, 'HEAD', $sig, $sig, null, 'Hello world!', $tree);
		git::commit_lookup($commit, $repo, $id);
		git::branch_create($ref, $repo, 'a', $commit, false);
		git::branch_create($ref, $repo, 'b', $commit, false);
		$this->assertOK(git::branch_iterator_new($iterator, $repo, git_branch_t::ALL));
		$this->assertInstanceOf(git_branch_iterator::class, $iterator);

		$this->assertOK(git::branch_next($a, $ta, $iterator));
		$this->assertSame(git_branch_t::LOCAL, $ta);
		git::branch_name($name, $a);
		$this->assertSame('a', $name);

		$this->assertOK(git::branch_next($b, $tb, $iterator));
		$this->assertSame(git_branch_t::LOCAL, $tb);
		git::branch_name($name, $b);
		$this->assertSame('b', $name);

		$this->assertOK(git::branch_next($master, $tmaster, $iterator));
		$this->assertSame(git_branch_t::LOCAL, $tmaster);
		git::branch_name($name, $master);
		$this->assertSame('master', $name);

		$this->assertSame(git_error_code::ITEROVER, git::branch_next($_, $_2, $iterator));
	}

}