# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License;
# you may not use this file except in compliance with the Elastic License.

require "logstash/json"
require 'license_checker/license_reader'
require 'license_checker/x_pack_info'
java_import java.util.concurrent.Executors
java_import java.util.concurrent.TimeUnit

module LogStash
  module LicenseChecker
    class LicenseError < StandardError; end

    class LicenseManager
      include LogStash::Util::Loggable, Observable

      attr_reader :last_updated

      def initialize(reader, feature, refresh_period = 30, refresh_unit = TimeUnit::SECONDS)
        @license_reader = reader
        @feature = feature

        fetch_license

        if @executor.nil?
            @executor = Executors.new_single_thread_scheduled_executor { |runnable| create_daemon_thread (runnable)}
            @executor.schedule_at_fixed_rate(Proc.new {fetch_license}, refresh_period, refresh_period, refresh_unit)
        end
      end

      def current_xpack_info
        @xpack_info
      end

      def fetch_xpack_info
        xpack_info = @license_reader.fetch_xpack_info

        update_xpack_info(xpack_info)
      end

      def fetch_cluster_info
        @cluster_info = @license_reader.fetch_cluster_info
      end

      def build_flavor
        @cluster_info&.dig('version', 'build_flavor')
      end

      def serverless?
        build_flavor == 'serverless'
      end

      def fetch_license
        fetch_cluster_info
        if serverless?
          update_xpack_info XPackInfo.serverless_response
        else
          fetch_xpack_info
        end
      end

      private
      def update_xpack_info(xpack_info)
        return if xpack_info == @xpack_info

        @xpack_info = xpack_info
        logger.debug('updating observers of xpack info change') if logger.debug?
        changed
        notify_observers(current_xpack_info, serverless?)
      end

      # Create a daemon thread for the license checker to stop this thread from keeping logstash running in the
      # event of shutdown
      def create_daemon_thread(runnable)
        thread = java.lang.Thread.new(runnable, "#{@feature}-license-manager")
        thread.set_daemon(true)
        thread
      end
    end
  end
end
