class Sentry::Vernier::Profiler

def active_thread_id

def active_thread_id
  Thread.current.object_id
end

def initialize(configuration)

def initialize(configuration)
  @event_id = Utils.uuid
  @started = false
  @sampled = nil
  @profiling_enabled = defined?(Vernier) && configuration.profiling_enabled?
  @profiles_sample_rate = configuration.profiles_sample_rate
  @project_root = configuration.project_root
  @app_dirs_pattern = configuration.app_dirs_pattern
  @in_app_pattern = Regexp.new("^(#{@project_root}/)?#{@app_dirs_pattern}")
end

def log(message)

def log(message)
  Sentry.sdk_logger.debug(LOGGER_PROGNAME) { "[Profiler::Vernier] #{message}" }
end

def output

def output
  @output ||= Output.new(
    result,
    project_root: @project_root,
    app_dirs_pattern: @app_dirs_pattern,
    in_app_pattern: @in_app_pattern
  )
end

def profile_meta

def profile_meta
  {
    event_id: @event_id,
    version: "1",
    platform: "ruby"
  }
end

def record_lost_event(reason)

def record_lost_event(reason)
  Sentry.get_current_client&.transport&.record_lost_event(reason, "profile")
end

def set_initial_sample_decision(transaction_sampled)

def set_initial_sample_decision(transaction_sampled)
  unless @profiling_enabled
    @sampled = false
    return
  end
  unless transaction_sampled
    @sampled = false
    log("Discarding profile because transaction not sampled")
    return
  end
  case @profiles_sample_rate
  when 0.0
    @sampled = false
    log("Discarding profile because sample_rate is 0")
    return
  when 1.0
    @sampled = true
    return
  else
    @sampled = Random.rand < @profiles_sample_rate
  end
  log("Discarding profile due to sampling decision") unless @sampled
end

def start

def start
  return unless @sampled
  return if @started
  @started = ::Vernier.start_profile
  log("Started")
  @started
rescue RuntimeError => e
  # TODO: once Vernier raises something more dedicated, we should catch that instead
  if e.message.include?("Profile already started")
    log("Not started since running elsewhere")
  else
    log("Failed to start: #{e.message}")
  end
end

def stop

def stop
  return unless @sampled
  return unless @started
  @result = ::Vernier.stop_profile
  @started = false
  log("Stopped")
rescue RuntimeError => e
  if e.message.include?("Profile not started")
    log("Not stopped since not started")
  else
    log("Failed to stop Vernier: #{e.message}")
  end
end

def to_hash

def to_hash
  unless @sampled
    record_lost_event(:sample_rate)
    return EMPTY_RESULT
  end
  return EMPTY_RESULT unless result
  { **profile_meta, profile: output.to_h }
end