class ApiDocs::ServicesController < FrontendController

  class ApiFileDoesNotExist < StandardError; end

  delegate :api_files, :apis, to: 'self.class'

  class << self
    def forbidden_apis
      Rails.configuration.three_scale.finance_enabled ? [] : ['Billing API'.freeze]
    end

    def api_files
      API_FILES.except(*forbidden_apis.map { |name| api_system_name(name) })
    end

    def api_system_name(api_name)
      api_name.downcase.tr(' ', '_')
    end

    def api_names
      API_NAMES - forbidden_apis
    end

    def apis
      APIS.select { |api| api_names.include?(api[:name]) }
    end

    def verify_accessible_api_files_exist!
      api_names.each do |name|
        file_path = api_file_path(name)
        raise(ApiFileDoesNotExist, "file #{file_path} does not exist") unless File.exist?(file_path)
      end
    end

    def api_file_path(name)
      Rails.root.join('doc', 'active_docs', "#{name}.json")
    end
  end

  class ApiFile

    attr_reader :file_path, :system_name

    def initialize(file_path, system_name)
      @file_path   = file_path
      @system_name = system_name
    end

    def json
      parsed_content = JSON.parse(file_content)
      parsed_content['basePath'] = backend_base_host if backend_api?

      parsed_content
    end

    private

    def backend_base_host
      backend_config = System::Application.config.backend_client

      [
        backend_config[:public_url],
        backend_config[:url],
        "https://#{backend_config[:host]}"
      ].find(&:presence)
    end

    BACKEND_APIS = %w(service_management_api).freeze

    def backend_api?
      BACKEND_APIS.include?(system_name)
    end

    def file_content
      File.exist?(file_path) ? File.read(file_path) : '{}'
    end
  end

  API_NAMES = ['Service Management API'.freeze, 'Account Management API'.freeze, 'Analytics API'.freeze, 'Billing API'.freeze].freeze
  verify_accessible_api_files_exist!

  APIS = API_NAMES.map do |api_name|
    system_name = api_system_name(api_name)

    {
        name:        api_name,
        system_name: system_name,
        description: '',
        path:        "/api_docs/services/#{system_name}.json"
    }
  end.freeze

  API_FILES = APIS.each_with_object({}) do |api, files|
    file_path = api_file_path(api[:name])
    api_json  = ApiFile.new(file_path, api[:system_name]).json

    files[api[:system_name]] = api_json
  end.freeze

  def index
    render json: { host: '', apis: apis }
  end

  def show
    api_file = api_files.fetch(params[:id]) { raise ActiveRecord::RecordNotFound }
    render json: api_file
  end
end
