# frozen_string_literal: true

require 'indicina/logging'

require 'parallel'
require 'tilt'

module Indicina
  class Generator
    extend Logging

    attr_accessor :suite, :definition, :report

    def initialize(name, report)
      data = File.read(File.join(suite_folder, "#{name}.json"))
      @definition = Mash.new(JSON.parse(data))

      @suite = TestSuite.find_or_create(name: name)
      @report = report

      report_range = definition.reports[report]
      suite.date_range = Time.parse(report_range.start_date)..Time.parse(report_range.end_date)
    end

    def generate
      start_time = Time.now
      important "Generating a report for the #{suite.name} test suite."
      render { sass :indicina, 'indicina.css' }

      render do |suite, report|
        @report = report
        @suite = suite

        slim :report, "#{suite.name}/#{report}.html"
      end

      important "Generated in #{format('%.3f', Time.now - start_time)} seconds."
    end

    # Rendering

    def render(&block)
      RenderScope.new.instance_exec(suite, report, &block)
    end

    class RenderScope < BasicObject
      extend Logging

      def get_template(name, extension: 'slim')
        @templates ||= {}
        @templates[name] ||= ::Tilt.new(::File.join(::Indicina::TEMPLATE_PATH, "#{name}.#{extension}"), pretty: true)
      end

      def slim(template, target, scope: nil)
        content = get_template(:layout).render(scope || self, {}) { get_template(template).render(scope || self, {}) }

        path = ::File.join(::Indicina::OUTPUT_PATH, target)
        ::FileUtils.mkdir_p(::File.dirname(path))
        ::File.open(path, 'w') { |f| f.puts content }
      end

      def sass(template, target, scope: nil)
        content = get_template(template, extension: 'sass').render(scope || self, {})

        path = ::File.join(::Indicina::OUTPUT_PATH, target)
        ::FileUtils.mkdir_p(::File.dirname(path))
        ::File.open(path, 'w') { |f| f.puts content }
      end
    end

    # Helpers
    def suite_folder
      @suite_folder ||= File.expand_path('../../../suites', __FILE__)
    end
  end
end

