#!/usr/bin/env fish

set -l project_root (path resolve (path dirname (status filename))/..)

function __test_fail --argument-names message
    printf 'not ok - %s\n' "$message" >&2
    exit 1
end

function __test_assert_equal --argument-names expected actual message
    test "$expected" = "$actual"
    or __test_fail "$message: expected <$expected>, got <$actual>"
end

function __test_is_tide_hex_color --argument-names name
    string match -q 'tide_*color*' -- $name
    and test (count $$name) -eq 1
    and string match -qr '^[0-9A-Fa-f]{6}$' -- $$name
end

function __test_snapshot --argument-names include_colors
    for name in (set --universal --names | string match -e -r '^tide_')
        __test_is_tide_hex_color $name
        set -l is_color $status
        if test "$include_colors" = yes
            test $is_color -eq 0; or continue
        else
            test $is_color -ne 0; or continue
        end
        printf '%s=%s\n' $name (string escape -- $$name)
    end
end

set -l light_mapper $project_root/functions/__tide_terminal_light_color.fish
set -l appearance_applicator $project_root/functions/__tide_apply_terminal_appearance.fish

test -f $light_mapper
or __test_fail "missing light palette mapper"
test -f $appearance_applicator
or __test_fail "missing terminal appearance applicator"

source $light_mapper
source $appearance_applicator

__test_assert_equal E4E4E4 (__tide_terminal_light_color 303030) \
    "dark segment background maps to the light segment background"
__test_assert_equal 006C9E (__tide_terminal_light_color 00AFFF) \
    "bright blue maps to its contrast-safe light equivalent"
__test_assert_equal CF0000 (__tide_terminal_light_color FF0000) \
    "bright red maps to its contrast-safe light equivalent"
__test_assert_equal glyph (__tide_terminal_light_color glyph) \
    "non-color values are preserved"

set -l empty_palette_result (
    fish --no-config -c '
        source $argv[1]
        source $argv[2]
        __tide_apply_terminal_appearance light
        printf "status=%s" $status
    ' $light_mapper $appearance_applicator 2>&1 |
        string collect
)
__test_assert_equal status=2 $empty_palette_result \
    "an unconfigured Tide palette is rejected without errors"

set -l expected_color_names
set -l expected_dark_colors
for name in (set --universal --names | string match -e -r '^tide_')
    if __test_is_tide_hex_color $name
        set --append expected_color_names $name
        set --append expected_dark_colors $$name
    end
end

test (count $expected_color_names) -gt 0
or __test_fail "the test fixture has no Tide colors"

set -l before_non_colors (string join \x1e (__test_snapshot no))

__tide_apply_terminal_appearance light
__test_assert_equal 0 $status "light appearance applies successfully"
__test_assert_equal E4E4E4 $tide_pwd_bg_color \
    "light appearance replaces the existing prompt segment background"
__test_assert_equal 006C9E $tide_pwd_color_anchors \
    "light appearance replaces the existing prompt foreground"

set -l pwd_scope (set --show tide_pwd_bg_color | string collect)
string match -q '*set in global scope, exported*' -- $pwd_scope
or __test_fail "Tide overrides are not global and exported"

set -l child_background (fish --no-config -c 'printf %s "$tide_pwd_bg_color"')
__test_assert_equal E4E4E4 $child_background \
    "Tide renderer subprocess inherits the light background"

set -l after_non_colors (string join \x1e (__test_snapshot no))
__test_assert_equal "$before_non_colors" "$after_non_colors" \
    "non-color Tide configuration remains unchanged"

set -l first_light_state
for name in $expected_color_names
    set --append first_light_state "$name="(string escape -- $$name)
end

__tide_apply_terminal_appearance light
__test_assert_equal 1 $status "repeated light appearance is a no-op"

set -l second_light_state
for name in $expected_color_names
    set --append second_light_state "$name="(string escape -- $$name)
end
__test_assert_equal (string join \x1e $first_light_state) \
    (string join \x1e $second_light_state) \
    "repeated light appearance preserves all color overrides"

begin
    for index in (seq (count $expected_dark_colors))
        set -l dark (string upper -- $expected_dark_colors[$index])
        test "$dark" = 303030; and continue
        printf '%s %s\n' $dark (__tide_terminal_light_color $dark)
    end
end | node $project_root/tests/assert_tide_light_contrast.mjs
or __test_fail "light palette foreground contrast is below 4.5:1"

__tide_apply_terminal_appearance dark
__test_assert_equal 0 $status "dark appearance applies successfully"

for index in (seq (count $expected_color_names))
    set -l name $expected_color_names[$index]
    __test_assert_equal $expected_dark_colors[$index] $$name \
        "dark appearance restores $name exactly"
end

__tide_apply_terminal_appearance invalid
__test_assert_equal 2 $status "invalid appearance is rejected"
__test_assert_equal dark $__tide_terminal_appearance \
    "invalid appearance does not change active state"

set -l integration $project_root/conf.d/tide_terminal_appearance.fish
test -f $integration
or __test_fail "missing live terminal appearance integration"

set -l integration_output (
    env TERM=xterm-kitty fish --interactive --no-config \
        $project_root/tests/inspect_tide_terminal_handler.fish |
        string collect
)
set -l handler_line (
    string split \n -- $integration_output |
        string match 'HANDLER|*'
)
string match -q \
    '*fish_terminal_color_theme __tide_terminal_color_theme_changed*' \
    -- $handler_line
or __test_fail "integration does not subscribe to Fish's terminal color theme"

string match -q '*LEGACY_BINDINGS|absent*' -- $integration_output
or __test_fail "integration still installs raw terminal response bindings"

printf 'ok - Tide terminal palette behavior\n'
