require 'spec_helper'

RSpec.describe Jekyll::Tags::AssetTag do
  let(:site) { create_test_site }
  let(:context) { create_liquid_context(site) }
  let(:skyhook) { Jekyll::Skyhook.instance(site) }

  before do
    # Create test assets
    create_test_css(site, 'assets/styles.css')
    create_test_js(site, 'assets/app.js')
    create_test_image(site, 'assets/logo.png', 100, 100)

    # Process assets to generate digests
    skyhook.process_assets
  end

  after do
    FileUtils.rm_rf(site.source)
    FileUtils.rm_rf(site.dest)
    FileUtils.rm_rf(site.cache_dir)
  end

  describe '#render' do
    it 'returns digested path for CSS files' do
      tag = create_tag(Jekyll::Tags::AssetTag, 'assets/styles.css')
      result = tag.render(context)

      expect(result).to start_with('/_digested/assets/styles-')
      expect(result).to end_with('.css')
    end

    it 'returns digested path for JS files' do
      tag = create_tag(Jekyll::Tags::AssetTag, 'assets/app.js')
      result = tag.render(context)

      expect(result).to start_with('/_digested/assets/app-')
      expect(result).to end_with('.js')
    end

    it 'returns digested path for image files' do
      tag = create_tag(Jekyll::Tags::AssetTag, 'assets/logo.png')
      result = tag.render(context)

      expect(result).to start_with('/_digested/assets/logo-')
      expect(result).to end_with('.png')
    end

    it 'processes liquid variables in asset paths' do
      var_context = create_liquid_context(site, { 'css_file' => 'assets/styles.css' })
      tag = create_tag(Jekyll::Tags::AssetTag, '{{ css_file }}')
      result = tag.render(var_context)

      expect(result).to start_with('/_digested/assets/styles-')
      expect(result).to end_with('.css')
    end

    it 'handles nested asset paths' do
      create_test_css(site, 'assets/css/main.css')
      skyhook.process_assets

      tag = create_tag(Jekyll::Tags::AssetTag, 'assets/css/main.css')
      result = tag.render(context)

      expect(result).to start_with('/_digested/assets/css/main-')
      expect(result).to end_with('.css')
    end

    it 'raises error for missing assets' do
      tag = create_tag(Jekyll::Tags::AssetTag, 'assets/missing.css')

      expect { tag.render(context) }.to raise_error(KeyError)
    end

    it 'generates consistent digests for identical content' do
      # Create two identical CSS files
      create_test_css(site, 'assets/styles1.css', 'body { color: red; }')
      create_test_css(site, 'assets/styles2.css', 'body { color: red; }')
      skyhook.process_assets

      tag1 = create_tag(Jekyll::Tags::AssetTag, 'assets/styles1.css')
      tag2 = create_tag(Jekyll::Tags::AssetTag, 'assets/styles2.css')

      result1 = tag1.render(context)
      result2 = tag2.render(context)

      # Extract digests
      digest1 = result1.match(/-([a-f0-9]{32})\./)[1]
      digest2 = result2.match(/-([a-f0-9]{32})\./)[1]

      expect(digest1).to eq(digest2)
    end

    it 'generates different digests for different content' do
      # Create two different CSS files
      create_test_css(site, 'assets/styles1.css', 'body { color: red; }')
      create_test_css(site, 'assets/styles2.css', 'body { color: blue; }')
      skyhook.process_assets

      tag1 = create_tag(Jekyll::Tags::AssetTag, 'assets/styles1.css')
      tag2 = create_tag(Jekyll::Tags::AssetTag, 'assets/styles2.css')

      result1 = tag1.render(context)
      result2 = tag2.render(context)

      # Extract digests
      digest1 = result1.match(/-([a-f0-9]{32})\./)[1]
      digest2 = result2.match(/-([a-f0-9]{32})\./)[1]

      expect(digest1).not_to eq(digest2)
    end
  end

  describe 'file watching behavior' do
    it 'updates digests when files change' do
      tag = create_tag(Jekyll::Tags::AssetTag, 'assets/styles.css')
      original_result = tag.render(context)

      # Modify the CSS file
      create_test_css(site, 'assets/styles.css', 'body { color: green; }')
      skyhook.process_assets

      # Digest should change
      new_result = tag.render(context)
      expect(new_result).not_to eq(original_result)

      # But both should be valid digested paths
      expect(original_result).to match(%r{/_digested/assets/styles-[a-f0-9]{32}\.css})
      expect(new_result).to match(%r{/_digested/assets/styles-[a-f0-9]{32}\.css})
    end
  end

  describe 'static file registration' do
    it 'registers digested assets as Jekyll static files' do
      # Check that our digested assets are included as static files
      asset_files = site.static_files.map(&:name)
      expect(asset_files.any? { |f| f.include?('styles-') && f.end_with?('.css') }).to be true
      expect(asset_files.any? { |f| f.include?('app-') && f.end_with?('.js') }).to be true
      expect(asset_files.any? { |f| f.include?('logo-') && f.end_with?('.png') }).to be true

      # Should have at least 3 digested files
      digested_files = site.static_files.select { |f| f.name.match?(/.*-[a-f0-9]{32}\./) }
      expect(digested_files.length).to be >= 3
    end
  end
end
