# frozen_string_literal: true

require "net/http"

class Link < ApplicationRecord
  belongs_to :link_category
  has_and_belongs_to_many :checks

  has_rich_text :description

  validates :url, :text, presence: true
  validate :check_url
  validate :valid_url

  before_validation :ensure_absolute_url

  def t_text
    text
  end

  def ok?
    fail_count.zero?
  end

  def to_s
    "#{text} (#{url})"
  end

  private

  USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"

  def check_url(input = url, add_error = true)
    response = begin
      Net::HTTP.get_response(URI.parse(input), 'User-Agent': USER_AGENT)
    rescue Socket::ResolutionError
      errors.add(:url, :invalid) if add_error
      return false
    end

    case response
    when Net::HTTPSuccess
      self.last_check_at = Time.zone.now
      self.fail_count = 0

      true
    when Net::HTTPRedirection
      check_url(response[:location])
    else
      self.last_check_at = Time.zone.now
      self.fail_count += 1
      errors.add(:url, :invalid) if add_error

      false
    end
  end

  def ensure_absolute_url
    self.url = "https://#{url}" unless url.match?(%r{https{0,1}://.*})
  end

  def valid_url
    errors.add(:url, :invalid) unless url.match(/\A#{URI::DEFAULT_PARSER.make_regexp(%w[http https])}\z/)
  end
end
