package com.gzzm.lobster.sandbox;

import org.junit.Test;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class SandboxServiceValidationTest {

    @Test
    public void pythonRejectsJavascriptStyleComment() {
        try {
            SandboxService.validateLanguageSpecificSyntaxHints("python",
                    "print('start')\n// right-side decoration\nprint('done')\n");
            fail("expected SandboxException");
        } catch (SandboxException e) {
            assertTrue(e.getMessage().contains("//"));
            assertTrue(e.getMessage().contains("line 2"));
        }
    }

    @Test
    public void skillPathRequiresMatchingActivatedSkill() {
        try {
            SandboxService.validateSkillMountReferencesForCode(
                    "subprocess.run(['python3', '/skill/sys_pptx/scripts/office/soffice.py'])",
                    null);
            fail("expected SandboxException");
        } catch (SandboxException e) {
            assertTrue(e.getMessage().contains("activated_skill='sys_pptx'"));
        }
    }

    @Test
    public void matchingSkillPathIsAccepted() {
        SandboxService.validateSkillMountReferencesForCode(
                "subprocess.run(['python3', '/skill/sys_pptx/scripts/office/soffice.py'])",
                "sys_pptx");
    }

    @Test
    public void manifestReadRequiresInputRefs() {
        try {
            SandboxService.validateInputPathReferencesForCode(
                    "manifest = json.load(open('/inputs/manifest.json'))\npdf = manifest[0]['path']",
                    Collections.emptyList());
            fail("expected SandboxException");
        } catch (SandboxException e) {
            assertTrue(e.getMessage().contains("no input_refs"));
        }
    }

    @Test
    public void directInputFilePathIsRejected() {
        try {
            SandboxService.validateInputPathReferencesForCode(
                    "pdf = \"/inputs/00-张一鸣个人简历.pdf\"\nprint(pdf)",
                    Collections.singletonList("art_pdf"));
            fail("expected SandboxException");
        } catch (SandboxException e) {
            assertTrue(e.getMessage().contains("manifest[i]['path']"));
        }
    }

    @Test
    public void manifestPathWithInputsIsAccepted() {
        SandboxService.validateInputPathReferencesForCode(
                "manifest = json.load(open('/inputs/manifest.json'))\npdf = manifest[0]['path']",
                Collections.singletonList("art_pdf"));
    }

    @Test
    public void missingSkillFileIsRejectedBeforeDockerRun() throws Exception {
        Path dir = Files.createTempDirectory("skill-pptx-test");
        try {
            Files.createDirectories(dir.resolve("scripts"));
            try {
                SandboxService.validateReferencedSkillFilesExist(
                        "subprocess.run(['python', '/skill/sys_pptx/scripts/office/soffice.py'])",
                        "sys_pptx",
                        dir);
                fail("expected SandboxException");
            } catch (SandboxException e) {
                assertTrue(e.getMessage().contains("does not contain scripts/office/soffice.py"));
            }
        } finally {
            Files.deleteIfExists(dir.resolve("scripts"));
            Files.deleteIfExists(dir);
        }
    }

    @Test
    public void existingSkillFileIsAccepted() throws Exception {
        Path dir = Files.createTempDirectory("skill-pptx-test");
        try {
            Files.createDirectories(dir.resolve("scripts/office"));
            Files.write(dir.resolve("scripts/office/soffice.py"), new byte[] { 1 });
            SandboxService.validateReferencedSkillFilesExist(
                    "subprocess.run(['python', '/skill/sys_pptx/scripts/office/soffice.py'])",
                    "sys_pptx",
                    dir);
        } finally {
            Files.deleteIfExists(dir.resolve("scripts/office/soffice.py"));
            Files.deleteIfExists(dir.resolve("scripts/office"));
            Files.deleteIfExists(dir.resolve("scripts"));
            Files.deleteIfExists(dir);
        }
    }
}
