# frozen_string_literal: true

RSpec.describe DiscourseAi::AiBot::ArtifactsController do
  fab!(:user)
  fab!(:topic) { Fabricate(:private_message_topic, user: user) }
  fab!(:post) { Fabricate(:post, user: user, topic: topic) }
  fab!(:artifact) do
    AiArtifact.create!(
      user: user,
      post: post,
      name: "Test Artifact",
      html: "<div>Hello World</div>",
      css: "div { color: blue; }",
      js: "console.log('test');",
      metadata: {
        public: false,
      },
    )
  end

  def parse_srcdoc(html)
    Nokogiri.HTML5(html).at_css("iframe")["srcdoc"]
  end

  before do
    SiteSetting.discourse_ai_enabled = true
    SiteSetting.ai_artifact_security = "strict"
  end

  describe "#show" do
    it "returns 404 when discourse_ai is disabled" do
      SiteSetting.discourse_ai_enabled = false
      get "/discourse-ai/ai-bot/artifacts/#{artifact.id}"
      expect(response.status).to eq(404)
    end

    it "returns 404 when ai_artifact_security disables it" do
      SiteSetting.ai_artifact_security = "disabled"
      get "/discourse-ai/ai-bot/artifacts/#{artifact.id}"
      expect(response.status).to eq(404)
    end

    context "with private artifact" do
      it "returns 404 when user cannot see the post" do
        get "/discourse-ai/ai-bot/artifacts/#{artifact.id}"
        expect(response.status).to eq(404)
      end

      it "shows artifact when user can see the post" do
        sign_in(user)
        get "/discourse-ai/ai-bot/artifacts/#{artifact.id}"
        expect(response.status).to eq(200)
        untrusted_html = parse_srcdoc(response.body)
        expect(untrusted_html).to include(artifact.html)
        expect(untrusted_html).to include(artifact.css)
        expect(untrusted_html).to include(artifact.js)
      end

      it "can also find an artifact by its version" do
        sign_in(user)

        version = artifact.create_new_version(html: "<div>Was Updated</div>")

        get "/discourse-ai/ai-bot/artifacts/#{artifact.id}/#{version.version_number}"
        expect(response.status).to eq(200)
        untrusted_html = parse_srcdoc(response.body)
        expect(untrusted_html).to include("Was Updated")
        expect(untrusted_html).to include(artifact.css)
        expect(untrusted_html).to include(artifact.js)
      end
    end

    context "with public artifact" do
      before { artifact.update!(metadata: { public: true }) }

      it "shows artifact without authentication" do
        get "/discourse-ai/ai-bot/artifacts/#{artifact.id}"
        expect(response.status).to eq(200)
        expect(parse_srcdoc(response.body)).to include(artifact.html)
      end
    end

    it "removes security headers and disables crawling" do
      sign_in(user)
      get "/discourse-ai/ai-bot/artifacts/#{artifact.id}"
      expect(response.headers["X-Frame-Options"]).to eq(nil)
      expect(response.headers["Content-Security-Policy"]).to include("unsafe-inline")
      expect(response.headers["X-Robots-Tag"]).to eq("noindex")
    end
  end
end
