/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * ---------------------------------------------------------------------
 *
 * Portions of this file were modified and ported to Vala by Victor Vintorez in 2026.
 * These modifications are licensed under the European Union Public License (EUPL),
 * Version 1.2 or later. You may obtain a copy of the License at:
 * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
 */

using GLib;
using MaterialColorUtilities;

public class ScoreTest : McuTestCase {
	public ScoreTest () {
		base ("score");
		add_test ("prioritizes_chroma", test_prioritizes_chroma);
		add_test ("prioritizes_chroma_when_proportions_equal", test_prioritizes_chroma_when_proportions_equal);
		add_test ("generates_google_blue_when_no_colors_available", test_generates_google_blue_when_no_colors_available);
		add_test ("dedupes_nearby_hues", test_dedupes_nearby_hues);
		add_test ("maximized_hue_distance", test_maximized_hue_distance);
		add_test ("generated_scenario_one", test_generated_scenario_one);
		add_test ("generated_scenario_two", test_generated_scenario_two);
		add_test ("generated_scenario_three", test_generated_scenario_three);
		add_test ("generated_scenario_four", test_generated_scenario_four);
		add_test ("generated_scenario_five", test_generated_scenario_five);
		add_test ("generated_scenario_six", test_generated_scenario_six);
		add_test ("generated_scenario_seven", test_generated_scenario_seven);
		add_test ("generated_scenario_eight", test_generated_scenario_eight);
		add_test ("generated_scenario_nine", test_generated_scenario_nine);
		add_test ("generated_scenario_ten", test_generated_scenario_ten);
	}

	public override void set_up () {}

	public void test_prioritizes_chroma () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff000000u, 1);
		colors.insert ((int) 0xffffffffu, 1);
		colors.insert ((int) 0xff0000ffu, 1);
		var answer = Score.score (colors);

		McuAssert.ints_equal (answer.length, 1);
		McuAssert.int_and_uint_equal (answer[0], 0xff0000ffu);
	}

	public void test_prioritizes_chroma_when_proportions_equal () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xffff0000u, 1);
		colors.insert ((int) 0xff00ff00u, 1);
		colors.insert ((int) 0xff0000ffu, 1);
		var answer = Score.score (colors);

		McuAssert.ints_equal (answer.length, 3);
		McuAssert.int_and_uint_equal (answer[0], 0xffff0000u);
		McuAssert.int_and_uint_equal (answer[1], 0xff00ff00u);
		McuAssert.int_and_uint_equal (answer[2], 0xff0000ffu);
	}

	public void test_generates_google_blue_when_no_colors_available () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff000000u, 1);
		var answer = Score.score (colors);

		McuAssert.ints_equal (answer.length, 1);
		McuAssert.int_and_uint_equal (answer[0], 0xff4285f4u);
	}

	public void test_dedupes_nearby_hues () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff008772u, 1);
		colors.insert ((int) 0xff318477u, 1);
		var answer = Score.score (colors);

		McuAssert.ints_equal (answer.length, 1);
		McuAssert.int_and_uint_equal (answer[0], 0xff008772u);
	}

	public void test_maximized_hue_distance () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff008772u, 1);
		colors.insert ((int) 0xff008587u, 1);
		colors.insert ((int) 0xff007ebcu, 1);
		var answer = Score.score (colors, 2);

		McuAssert.ints_equal (answer.length, 2);
		McuAssert.int_and_uint_equal (answer[0], 0xff007ebcu);
		McuAssert.int_and_uint_equal (answer[1], 0xff008772u);
	}

	public void test_generated_scenario_one () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff7ea16du, 67);
		colors.insert ((int) 0xffd8ccaeu, 67);
		colors.insert ((int) 0xff835c0du, 49);
		var answer = Score.score (colors, 3, (int) 0xff8d3819u, false);

		McuAssert.ints_equal (answer.length, 3);
		McuAssert.int_and_uint_equal (answer[0], 0xff7ea16du);
		McuAssert.int_and_uint_equal (answer[1], 0xffd8ccaeu);
		McuAssert.int_and_uint_equal (answer[2], 0xff835c0du);
	}

	public void test_generated_scenario_two () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xffd33881u, 14);
		colors.insert ((int) 0xff3205ccu, 77);
		colors.insert ((int) 0xff0b48cfu, 36);
		colors.insert ((int) 0xffa08f5du, 81);
		var answer = Score.score (colors, 4, (int) 0xff7d772bu, true);

		McuAssert.ints_equal (answer.length, 3);
		McuAssert.int_and_uint_equal (answer[0], 0xff3205ccu);
		McuAssert.int_and_uint_equal (answer[1], 0xffa08f5du);
		McuAssert.int_and_uint_equal (answer[2], 0xffd33881u);
	}

	public void test_generated_scenario_three () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xffbe94a6u, 23);
		colors.insert ((int) 0xffc33fd7u, 42);
		colors.insert ((int) 0xff899f36u, 90);
		colors.insert ((int) 0xff94c574u, 82);
		var answer = Score.score (colors, 3, (int) 0xffaa79a4u, true);

		McuAssert.ints_equal (answer.length, 3);
		McuAssert.int_and_uint_equal (answer[0], 0xff94c574u);
		McuAssert.int_and_uint_equal (answer[1], 0xffc33fd7u);
		McuAssert.int_and_uint_equal (answer[2], 0xffbe94a6u);
	}

	public void test_generated_scenario_four () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xffdf241cu, 85);
		colors.insert ((int) 0xff685859u, 44);
		colors.insert ((int) 0xffd06d5fu, 34);
		colors.insert ((int) 0xff561c54u, 27);
		colors.insert ((int) 0xff713090u, 88);
		var answer = Score.score (colors, 5, (int) 0xff58c19cu, false);

		McuAssert.ints_equal (answer.length, 2);
		McuAssert.int_and_uint_equal (answer[0], 0xffdf241cu);
		McuAssert.int_and_uint_equal (answer[1], 0xff561c54u);
	}

	public void test_generated_scenario_five () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xffbe66f8u, 41);
		colors.insert ((int) 0xff4bbda9u, 88);
		colors.insert ((int) 0xff80f6f9u, 44);
		colors.insert ((int) 0xffab8017u, 43);
		colors.insert ((int) 0xffe89307u, 65);
		var answer = Score.score (colors, 3, (int) 0xff916691u, false);

		McuAssert.ints_equal (answer.length, 3);
		McuAssert.int_and_uint_equal (answer[0], 0xffab8017u);
		McuAssert.int_and_uint_equal (answer[1], 0xff4bbda9u);
		McuAssert.int_and_uint_equal (answer[2], 0xffbe66f8u);
	}

	public void test_generated_scenario_six () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff18ea8fu, 93);
		colors.insert ((int) 0xff327593u, 18);
		colors.insert ((int) 0xff066a18u, 53);
		colors.insert ((int) 0xfffa8a23u, 74);
		colors.insert ((int) 0xff04ca1fu, 62);
		var answer = Score.score (colors, 2, (int) 0xff4c377au, false);

		McuAssert.ints_equal (answer.length, 2);
		McuAssert.int_and_uint_equal (answer[0], 0xff18ea8fu);
		McuAssert.int_and_uint_equal (answer[1], 0xfffa8a23u);
	}

	public void test_generated_scenario_seven () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff2e05edu, 23);
		colors.insert ((int) 0xff153e55u, 90);
		colors.insert ((int) 0xff9ab220u, 23);
		colors.insert ((int) 0xff153379u, 66);
		colors.insert ((int) 0xff68bcc3u, 81);
		var answer = Score.score (colors, 2, (int) 0xfff588dcu, true);

		McuAssert.ints_equal (answer.length, 2);
		McuAssert.int_and_uint_equal (answer[0], 0xff2e05edu);
		McuAssert.int_and_uint_equal (answer[1], 0xff9ab220u);
	}

	public void test_generated_scenario_eight () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff816ec5u, 24);
		colors.insert ((int) 0xff6dcb94u, 19);
		colors.insert ((int) 0xff3cae91u, 98);
		colors.insert ((int) 0xff5b542fu, 25);
		var answer = Score.score (colors, 1, (int) 0xff84b0fdu, false);

		McuAssert.ints_equal (answer.length, 1);
		McuAssert.int_and_uint_equal (answer[0], 0xff3cae91u);
	}

	public void test_generated_scenario_nine () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff206f86u, 52);
		colors.insert ((int) 0xff4a620du, 96);
		colors.insert ((int) 0xfff51401u, 85);
		colors.insert ((int) 0xff2b8ebfu, 3);
		colors.insert ((int) 0xff277766u, 59);
		var answer = Score.score (colors, 3, (int) 0xff02b415u, true);

		McuAssert.ints_equal (answer.length, 3);
		McuAssert.int_and_uint_equal (answer[0], 0xfff51401u);
		McuAssert.int_and_uint_equal (answer[1], 0xff4a620du);
		McuAssert.int_and_uint_equal (answer[2], 0xff2b8ebfu);
	}

	public void test_generated_scenario_ten () {
		var colors = new HashTable<int, int> (direct_hash, direct_equal);
		colors.insert ((int) 0xff8b1d99u, 54);
		colors.insert ((int) 0xff27effeu, 43);
		colors.insert ((int) 0xff6f558du, 2);
		colors.insert ((int) 0xff77fdf2u, 78);
		var answer = Score.score (colors, 4, (int) 0xff5e7a10u, true);

		McuAssert.ints_equal (answer.length, 3);
		McuAssert.int_and_uint_equal (answer[0], 0xff27effeu);
		McuAssert.int_and_uint_equal (answer[1], 0xff8b1d99u);
		McuAssert.int_and_uint_equal (answer[2], 0xff6f558du);
	}

	public override void tear_down () {}
}
