<?php
/*
 * Copyright (c) 2012, webvariants GbR, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 */

class RealURL2_ResolverTest extends RealURL2_BaseTest {
	/**
	 * @dataProvider simpleProvider
	 */
	public function testSimpleResolving($expected, $url) {
		self::rebuildAll();

		$storage  = WV24_Util::getStorage();
		$resolver = new _WV24_Resolver($storage, sly_Core::cache());
		$result   = $resolver->resolveUrl($url);

		if ($expected === null) {
			$this->assertNull($result);
			return;
		}

		$this->assertInstanceof('_WV24_URL', $result);
		$this->assertEquals($expected, $result->getIdent());
	}

	public function simpleProvider() {
		return array(
			// vanilla cases
			array('98_5', 'http://cli/'),
			array('98_8', 'http://cli/en/'),
			array('49_8', 'http://cli/en/Computer+virus/'),
			array('90_5', 'http://cli/ackermannfunktion.html'),

			// remove params
			array('90_5', 'http://cli/ackermannfunktion.html?params'),
			array('90_5', 'http://cli/ackermannfunktion.html?params&more'),
			array('90_5', 'http://cli/ackermannfunktion.html&broken'),

			// replace index files automatically
			array('98_5', 'http://cli/index.html'),
			array('98_5', 'http://cli/index.php'),

			// fix missing slash
			array('98_5', 'http://cli'),
			array('98_8', 'http://cli/en'),

			// don't attempt to fix article URLs
			array(null, 'http://cli/ackermannX.html'),

			// fix domain
			array('98_5', 'http://dummy.com/'),
			array('98_8', 'http://dummy.com/en/'),

			// fix domain and path
			array('98_8', 'http://dummy.com/en'),
			array('98_8', 'http://dummy.com/en/index.html'),
		);
	}

	/**
	 * @dataProvider getPositionsProvider
	 */
	public function testGetPositions($id, $clang, $expected) {
		$storage   = WV24_Util::getStorage();
		$resolver  = new _WV24_Resolver($storage, sly_Core::cache());
		$article   = sly_Util_Article::findById($id, $clang);
		$positions = $resolver->computePositions($article);

		$this->assertEquals($expected, $positions);
	}

	public function getPositionsProvider() {
		return array(
			array(48, 5, array(1)),
				array(1, 5, array(1,1)),
				array(2, 5, array(1,2)),
					array(16,  5, array(1,2,2)),
					array(101, 5, array(1,2,4)),
				array(4, 5, array(1,4)),
					array(21, 5, array(1,4,2)),
			array(49, 5, array(2)),
					array(76, 5, array(2,2,1)),
			array(98, 5, array(3)),
			array(90, 5, array(4)),
		);
	}

	/**
	 * @dataProvider conflictResolutionProvider
	 */
	public function testConflictResolution($expectedIdent, $expectedCount, array $operations, $url) {
		$db = sly_DB_Persistence::getInstance();

		foreach ($operations as $id => $fragment) {
			$db->update('article', array('wv24_fragment' => $fragment), array('id' => $id, 'clang' => 5));
		}

		// rebuild all URLs
		self::rebuildAll();

		// prepare
		$storage  = WV24_Util::getStorage();
		$resolver = new _WV24_Resolver($storage, new BabelCache_Blackhole());

		// check if all conflicted URLs were found
		$result = $resolver->findUrl($url, true);
		$this->assertEquals($expectedCount, is_array($result) ? count($result) : 1);

		if ($expectedCount === 0) {
			return;
		}

		// check if the resolution worked as expected
		$result = $resolver->resolveUrl($url);

		$this->assertInstanceof('_WV24_URL', $result);
		$this->assertEquals($expectedIdent, $result->getIdent());
	}

	public function conflictResolutionProvider() {
		return array(
			array('90_5', 2, array(90 => '/'), 'http://cli/'),
			array('98_5', 2, array(48 => '/'), 'http://cli/'),
			array('90_5', 3, array(48 => '/', 90 => '/'), 'http://cli/'),

			// real-world-case: make C64 a domain and let the first category be the root
			array('1_5', 2, array(48 => '//c64.com', 1 => '/'), 'http://c64.com/'),

			// articles/categories that are lower (higher [cat]pos) have priority
			array('2_5', 3, array(48 => '//c64.com', 1 => '/', 2 => '/'), 'http://c64.com/'),

			// let deeper categories override the parent
			array('15_5', 3, array(48 => '//c64.com', 1 => '/', 15 => '/'), 'http://c64.com/'),

			// lower is more important than depth
			array('3_5', 4, array(48 => '//c64.com', 2 => '/', 3 => '/', 15 => '/'), 'http://c64.com/'),

			// check priority between totally different trees
			array('56_5', 2, array(2 => '//c64.com', 56 => '//c64.com'), 'http://c64.com/'),
			array('56_5', 2, array(48 => '//c64.com', 56 => '//c64.com'), 'http://c64.com/'),
			array('56_5', 2, array(49 => '//c64.com', 56 => '//c64.com'), 'http://c64.com/'),
			array('76_5', 2, array(50 => '//c64.com', 76 => '//c64.com'), 'http://c64.com/'),
		);
	}
}
