# frozen_string_literal: true

require 'octokit'
require 'redis'
require_relative '../../config/constants'

module Matterhorn
  class GitHub
    class << self
      def github
        @github ||= begin
          ghe = Octokit::Client.new(access_token: GITHUB_ACCESS_TOKEN)
          ghe.auto_paginate = true
          ghe
        end
      end

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

      def set_cache(key, value, expire_seconds: 300)
        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:gh', method: nil, key:)
        "#{prefix}:#{method}:#{key}"
      end

      def teams_for_repository(repo, filter, filter_id = 'all')
        key = cache_key_for method: 'teams_for_repository', key: "#{repo}-#{filter_id}"
        teams = get_cache(key)
        teams || begin
          github_teams = github.teams(repo)
          github_teams = github_teams.select { |a| filter.include?(a[:name]) } if filter
          set_cache key, github_teams.map(&:to_h)
          github_teams
        end
      end

      def team_membership(team_id, username)
        key = cache_key_for method: 'team_member', key: "user-#{username}-team-#{team_id}"
        membership = get_cache(key)
        membership || begin
          github_membership = github.team_membership(team_id, username).to_h
          set_cache key, github_membership
          github_membership
        rescue Octokit::NotFound
          github_membership = false
          set_cache key, github_membership
          github_membership
        end
      end

      def pull_request(repo, number)
        key = cache_key_for method: 'pull_request', key: "#{repo}-pr-#{number}"
        pull_request = get_cache(key)
        pull_request || begin
          github_pull_request = github.pull_request(repo, number)
          set_cache key, github_pull_request.to_h
          github_pull_request
        end
      end

      def pull_request_commits(repo, number)
        key = cache_key_for method: 'pull_request_commits', key: "#{repo}-pr-#{number}"
        pull_request_commits = get_cache(key)
        pull_request_commits || begin
          github_pull_request_commits = github.pull_request_commits(repo, number)
          set_cache key, github_pull_request_commits.map(&:to_h)
          github_pull_request_commits
        end
      end
    end
  end
end
