# frozen_string_literal: true

require 'redis'
require 'rest-client'
require_relative '../../config/constants'

module Matterhorn
  class TeamCity
    class << self
      include Matterhorn::Logger

      def api_request(url, method: :get)
        RestClient::Request.execute method: method, url: url, user: TEAMCITY_USERNAME, password: TEAMCITY_PASSWORD
      end

      def redis
        @redis ||= Redis.new(url: REDIS_URL)
      end

      def set_cache(key, value, expire_seconds: 30)
        redis.set(key, value.to_json)
        redis.expire(key, expire_seconds)
      end

      def get_cache(key)
        data = redis.get(key)
        data.nil? ? nil : JSON.parse(data)
      end

      def cache_key_for(prefix: 'matterhorn:tc', method: nil, key:)
        "#{prefix}:#{method}:#{key}"
      end

      def current_run(project, pull_request_number, commit_hash)
        recent_builds(project, pull_request_number).each do |build|
          next unless build.is_a?(Hash)
          data = build_details(build)
          return data if data['revisions'].to_s.include?(commit_hash)
        end
        {}
      end

      def recent_builds(project, pull_request_number)
        key = cache_key_for method: 'recent_builds', key: "#{project}:#{pull_request_number}"
        recent_builds = get_cache(key)
        recent_builds || begin
          url = "#{TEAMCITY_URL}/app/rest/builds?locator=buildType:#{PROJECTS[:projects][project][:teamcity][:build_type]},running:any,branch:#{pull_request_number}"
          builds = Hash.from_xml(api_request(url))['builds']['build'] || []
          builds = [builds] unless builds.is_a?(Array)
          set_cache key, builds
          builds
        end
      end

      def build_details(build)
        key = cache_key_for method: 'build_details', key: build['id']
        build_data = get_cache(key)
        build_data || begin
          url = "#{TEAMCITY_URL}#{build['href']}"
          data = Hash.from_xml(api_request(url))['build']
          set_cache key, data
          data
        end
      end
    end
  end
end
