require 'erb'
require 'active_support'
require 'active_support/core_ext'
require 'ansi/bbcode'

module Debci
  module HTMLHelpers
    include ERB::Util
    include ActiveSupport::NumberHelper

    ICONS = {
      pass: 'thumbs-up',
      neutral: 'minus-circle',
      fail: 'thumbs-down',
      fail_passed_never: ['thumbs-down', 'ban'],
      fail_passed_current: ['thumbs-down', 'bolt'],
      fail_passed_old: ['thumbs-down', 'arrow-down'],
      tmpfail_pass: 'thumbs-up',
      tmpfail_fail: 'thumbs-down',
      tmpfail: 'question-circle',
      no_test_data: 'question',
    }.freeze

    def icon(status)
      status ||= :no_test_data
      Array(ICONS[status.to_sym]).map do |i|
        "<i class='#{status} fa fa-#{i}'></i>"
      end.join(' ')
    end

    def file_link(size, link_pattern)
      return unless size
      link_pattern % number_to_human_size(size)
    end

    def title_test_trigger_pin(test)
      title = ''
      unless test.trigger.blank?
        title << "Trigger:\n"
        title << h(test.trigger)
      end
      if test.pinned?
        title << "\n\n" unless test.trigger.blank?
        title << "Pinned packages:\n"
        expand_pin_packages(test).each do |pin|
          title << pin << "\n"
        end
      end
      title
    end

    def expand_pin_packages(test)
      return [] unless test.pinned?

      test.pin_packages.map do |pin|
        *packages, suite = pin
        Array(packages).map do |pkglist|
          String(pkglist).split(/\s*,\s*/).map do |pkg|
            "#{pkg} from #{suite}"
          end
        end
      end.flatten
    end

    def pkg_history_url(package, suite, arch)
      "/packages/#{package.prefix}/#{package.name}/#{suite}/#{arch}/"
    end

    def history_url(job)
      pkg_history_url(job.package, job.suite, job.arch)
    end

    def package_url(package)
      "/packages/#{package.prefix}/#{package.name}/"
    end

    # expand { SUITE } macro in URLs
    def expand_url(url, suite)
      url&.gsub('{SUITE}', suite)
    end

    # Converts ANSI codes to HTML. Escapes any HTML before even looking for
    # ANSI codes.
    def ansi_to_html(str)
      return str unless str
      input = str.gsub(/</, '&lt;').gsub(/>/, '&gt;')
      return input unless input =~ /\e\[/
      begin
        result = ANSI::BBCode.ansi_to_html(input)
        result = result[0..-8] if result =~ %r{<br />\n$}
        result
      rescue StandardError
        # in case anything goes wrong with the conversion, just remove all ANSI
        # escape codes
        input.gsub(/\e\[[0-9;]+m/, "")
      end
    end
  end
end
