"""Tests for cli/context.py — app resolution chain."""

from __future__ import annotations

import os
import pathlib

import pytest

from kuberoku.cli.context import (
    AppResolutionError,
    resolve_app,
    resolve_app_and_cluster,
    resolve_project_link_for_display,
)
from kuberoku.config.project import write_project_file


class TestResolveApp:
    def test_flag_literal(self) -> None:
        assert resolve_app(app_flag="myapi") == "myapi"

    def test_flag_alias(self, tmp_path: pathlib.Path) -> None:
        write_project_file("myapi-staging", alias="staging", directory=tmp_path)
        # Change cwd to tmp_path so resolve_project_link finds it
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            assert resolve_app(app_flag="staging") == "myapi-staging"
        finally:
            os.chdir(old_cwd)

    def test_flag_not_alias(self, tmp_path: pathlib.Path) -> None:
        write_project_file("myapi-dev", alias="dev", directory=tmp_path)
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            # "literal" is not an alias, so it's used as-is
            assert resolve_app(app_flag="literal") == "literal"
        finally:
            os.chdir(old_cwd)

    def test_env_var(self, monkeypatch: pytest.MonkeyPatch) -> None:
        monkeypatch.setenv("KUBEROKU_APP", "envapp")
        assert resolve_app() == "envapp"

    def test_project_file(self, tmp_path: pathlib.Path) -> None:
        write_project_file("myapi", directory=tmp_path)
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            assert resolve_app() == "myapi"
        finally:
            os.chdir(old_cwd)

    def test_flag_beats_env(self, monkeypatch: pytest.MonkeyPatch) -> None:
        monkeypatch.setenv("KUBEROKU_APP", "envapp")
        assert resolve_app(app_flag="flagapp") == "flagapp"

    def test_env_beats_project_file(
        self, tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch
    ) -> None:
        monkeypatch.setenv("KUBEROKU_APP", "envapp")
        write_project_file("fileapp", directory=tmp_path)
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            assert resolve_app() == "envapp"
        finally:
            os.chdir(old_cwd)

    def test_no_source_raises(self, tmp_path: pathlib.Path) -> None:
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            with pytest.raises(AppResolutionError):
                resolve_app()
        finally:
            os.chdir(old_cwd)


class TestResolveAppAndCluster:
    def test_flag_with_cluster(self, tmp_path: pathlib.Path) -> None:
        write_project_file("myapi-prod", alias="prod", cluster="production", directory=tmp_path)
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            app, cluster = resolve_app_and_cluster(app_flag="prod")
            assert app == "myapi-prod"
            assert cluster == "production"
        finally:
            os.chdir(old_cwd)

    def test_flag_literal_no_cluster(self) -> None:
        app, cluster = resolve_app_and_cluster(app_flag="myapi")
        assert app == "myapi"
        assert cluster is None

    def test_env_var(self, monkeypatch: pytest.MonkeyPatch) -> None:
        monkeypatch.setenv("KUBEROKU_APP", "envapp")
        app, cluster = resolve_app_and_cluster()
        assert app == "envapp"
        assert cluster is None

    def test_project_file(self, tmp_path: pathlib.Path) -> None:
        write_project_file("myapi", cluster="local", directory=tmp_path)
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            app, cluster = resolve_app_and_cluster()
            assert app == "myapi"
            assert cluster == "local"
        finally:
            os.chdir(old_cwd)

    def test_no_source_raises(self, tmp_path: pathlib.Path) -> None:
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            with pytest.raises(AppResolutionError):
                resolve_app_and_cluster()
        finally:
            os.chdir(old_cwd)


class TestResolveProjectLinkForDisplay:
    def test_returns_none_when_no_file(self, tmp_path: pathlib.Path) -> None:
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            assert resolve_project_link_for_display() is None
        finally:
            os.chdir(old_cwd)

    def test_returns_link_when_file_exists(self, tmp_path: pathlib.Path) -> None:
        write_project_file("myapi", directory=tmp_path)
        old_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            link = resolve_project_link_for_display()
            assert link is not None
            assert link.app == "myapi"
        finally:
            os.chdir(old_cwd)
