# Copyright (c) 2025 CoReason, Inc.
#
# This software is proprietary and dual-licensed.
# Licensed under the Prosperity Public License 3.0 (the "License").
# A copy of the license is available at https://prosperitylicense.com/versions/3.0.0
# For details, see the LICENSE file.
# Commercial use beyond a 30-day trial requires a separate license.
#
# Source Code: https://github.com/CoReason-AI/coreason-manifest

import os
from pathlib import Path

import pytest
import yaml

from coreason_manifest import load


def test_symlink_bypass(tmp_path: Path) -> None:
    """Test that a symlink inside the jail pointing outside is blocked."""
    # 1. Create Secret Outside Jail
    secret_path = tmp_path / "secret.yaml"
    secret_path.write_text("secret: true", encoding="utf-8")

    # 2. Create Jail
    jail_dir = tmp_path / "jail"
    jail_dir.mkdir()

    # 3. Create Symlink inside Jail -> Outside
    link_path = jail_dir / "link_to_secret.yaml"

    try:
        os.symlink(secret_path, link_path)
    except (OSError, AttributeError, NotImplementedError):
        pytest.skip("Symlinks not supported on this platform/environment")

    # 4. Create Main Manifest referencing the Symlink
    main_manifest = {"definitions": {"leak": {"$ref": "link_to_secret.yaml"}}}
    main_path = jail_dir / "main.yaml"
    main_path.write_text(yaml.dump(main_manifest), encoding="utf-8")

    # 5. Attempt Load - Should fail because resolved path is outside jail
    with pytest.raises(ValueError, match="Security Error"):
        load(main_path, root_dir=jail_dir)


def test_absolute_path_traversal(tmp_path: Path) -> None:
    """Test that absolute paths pointing outside the jail are blocked."""
    secret_path = tmp_path / "secret.yaml"
    secret_path.write_text("data: sensitive", encoding="utf-8")

    jail_dir = tmp_path / "jail"
    jail_dir.mkdir()

    # Absolute path to the secret
    abs_secret = str(secret_path.resolve())

    main_manifest = {"definitions": {"abs": {"$ref": abs_secret}}}
    main_path = jail_dir / "main.yaml"
    main_path.write_text(yaml.dump(main_manifest), encoding="utf-8")

    with pytest.raises(ValueError, match="Security Error"):
        load(main_path, root_dir=jail_dir)


def test_path_normalization_traversal(tmp_path: Path) -> None:
    """Test convoluted paths that normalize to outside."""
    secret_path = tmp_path / "secret.yaml"
    secret_path.write_text("data: hidden", encoding="utf-8")

    jail_dir = tmp_path / "jail"
    jail_dir.mkdir()

    # Path: "subdir/../../secret.yaml" -> resolves to /tmp/secret.yaml
    ref_str = "subdir/../../secret.yaml"

    main_manifest = {"definitions": {"norm": {"$ref": ref_str}}}
    main_path = jail_dir / "main.yaml"
    main_path.write_text(yaml.dump(main_manifest), encoding="utf-8")

    (jail_dir / "subdir").mkdir()

    with pytest.raises(ValueError, match="Security Error"):
        load(main_path, root_dir=jail_dir)
