// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include "service/http_service.h"

#include <event2/bufferevent.h>
#include <event2/http.h>
#include <gen_cpp/FrontendService_types.h>

#include <string>
#include <vector>

#include "cloud/cloud_compaction_action.h"
#include "cloud/config.h"
#include "cloud/injection_point_action.h"
#include "common/config.h"
#include "common/status.h"
#include "http/action/adjust_log_level.h"
#include "http/action/adjust_tracing_dump.h"
#include "http/action/batch_download_action.h"
#include "http/action/be_proc_thread_action.h"
#include "http/action/calc_file_crc_action.h"
#include "http/action/check_rpc_channel_action.h"
#include "http/action/check_tablet_segment_action.h"
#include "http/action/checksum_action.h"
#include "http/action/clear_cache_action.h"
#include "http/action/compaction_action.h"
#include "http/action/compaction_score_action.h"
#include "http/action/config_action.h"
#include "http/action/debug_point_action.h"
#include "http/action/delete_bitmap_action.h"
#include "http/action/download_action.h"
#include "http/action/download_binlog_action.h"
#include "http/action/file_cache_action.h"
#include "http/action/health_action.h"
#include "http/action/http_stream.h"
#include "http/action/jeprofile_actions.h"
#include "http/action/load_stream_action.h"
#include "http/action/meta_action.h"
#include "http/action/metrics_action.h"
#include "http/action/pad_rowset_action.h"
#include "http/action/pipeline_task_action.h"
#include "http/action/pprof_actions.h"
#include "http/action/reload_tablet_action.h"
#include "http/action/report_action.h"
#include "http/action/reset_rpc_channel_action.h"
#include "http/action/restore_tablet_action.h"
#include "http/action/show_hotspot_action.h"
#include "http/action/show_nested_index_file_action.h"
#include "http/action/shrink_mem_action.h"
#include "http/action/snapshot_action.h"
#include "http/action/stream_load.h"
#include "http/action/stream_load_2pc.h"
#include "http/action/tablet_migration_action.h"
#include "http/action/tablets_distribution_action.h"
#include "http/action/tablets_info_action.h"
#include "http/action/version_action.h"
#include "http/default_path_handlers.h"
#include "http/ev_http_server.h"
#include "http/http_method.h"
#include "http/web_page_handler.h"
#include "olap/options.h"
#include "olap/storage_engine.h"
#include "runtime/exec_env.h"
#include "runtime/load_path_mgr.h"
#include "util/doris_metrics.h"

namespace doris {
#include "common/compile_check_begin.h"
namespace {
std::shared_ptr<bufferevent_rate_limit_group> get_rate_limit_group(event_base* event_base) {
    auto rate_limit = config::download_binlog_rate_limit_kbs;
    if (rate_limit <= 0) {
        return nullptr;
    }

    auto max_value = std::numeric_limits<int32_t>::max() / 1024 * 10;
    if (rate_limit > max_value) {
        LOG(WARNING) << "rate limit is too large, set to max value.";
        rate_limit = max_value;
    }
    struct timeval cfg_tick = {0, 100 * 1000}; // 100ms
    rate_limit = rate_limit / 10 * 1024;       // convert to KB/S

    auto token_bucket = std::unique_ptr<ev_token_bucket_cfg, decltype(&ev_token_bucket_cfg_free)>(
            ev_token_bucket_cfg_new(rate_limit, rate_limit * 2, rate_limit, rate_limit * 2,
                                    &cfg_tick),
            ev_token_bucket_cfg_free);
    return {bufferevent_rate_limit_group_new(event_base, token_bucket.get()),
            bufferevent_rate_limit_group_free};
}
} // namespace

HttpService::HttpService(ExecEnv* env, int port, int num_threads)
        : _env(env),
          _ev_http_server(new EvHttpServer(port, num_threads)),
          _web_page_handler(new WebPageHandler(_ev_http_server.get(), env)) {}

HttpService::~HttpService() {
    stop();
}

// NOLINTBEGIN(readability-function-size)
Status HttpService::start() {
    add_default_path_handlers(_web_page_handler.get());

    auto event_base = _ev_http_server->get_event_bases()[0];
    _rate_limit_group = get_rate_limit_group(event_base.get());

    // register load
    StreamLoadAction* streamload_action = _pool.add(new StreamLoadAction(_env));
    _ev_http_server->register_handler(HttpMethod::PUT, "/api/{db}/{table}/_load",
                                      streamload_action);
    _ev_http_server->register_handler(HttpMethod::PUT, "/api/{db}/{table}/_stream_load",
                                      streamload_action);
    StreamLoad2PCAction* streamload_2pc_action = _pool.add(new StreamLoad2PCAction(_env));
    _ev_http_server->register_handler(HttpMethod::PUT, "/api/{db}/_stream_load_2pc",
                                      streamload_2pc_action);
    _ev_http_server->register_handler(HttpMethod::PUT, "/api/{db}/{table}/_stream_load_2pc",
                                      streamload_2pc_action);

    // register http_stream
    HttpStreamAction* http_stream_action = _pool.add(new HttpStreamAction(_env));
    _ev_http_server->register_handler(HttpMethod::PUT, "/api/_http_stream", http_stream_action);

    DownloadAction* error_log_download_action =
            _pool.add(new DownloadAction(_env, _env->load_path_mgr()->get_load_error_file_dir()));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/_load_error_log",
                                      error_log_download_action);
    _ev_http_server->register_handler(HttpMethod::HEAD, "/api/_load_error_log",
                                      error_log_download_action);

    AdjustLogLevelAction* adjust_log_level_action = _pool.add(new AdjustLogLevelAction(_env));
    _ev_http_server->register_handler(HttpMethod::POST, "api/glog/adjust", adjust_log_level_action);

    //TODO: add query GET interface
    auto* adjust_tracing_dump = _pool.add(new AdjustTracingDump(_env));
    _ev_http_server->register_handler(HttpMethod::POST, "api/pipeline/tracing",
                                      adjust_tracing_dump);

    // Register BE version action
    VersionAction* version_action =
            _pool.add(new VersionAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::NONE));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/be_version_info", version_action);

    // Register BE health action
    HealthAction* health_action = _pool.add(new HealthAction(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/health", health_action);

    // Clear cache action
    ClearCacheAction* clear_cache_action = _pool.add(new ClearCacheAction(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/clear_cache/{type}",
                                      clear_cache_action);

    // Dump all running pipeline tasks
    PipelineTaskAction* pipeline_task_action = _pool.add(new PipelineTaskAction(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/running_pipeline_tasks",
                                      pipeline_task_action);

    // Dump all running pipeline tasks which has been running for more than {duration} seconds
    LongPipelineTaskAction* long_pipeline_task_action = _pool.add(new LongPipelineTaskAction(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/running_pipeline_tasks/{duration}",
                                      long_pipeline_task_action);

    // Dump all running pipeline tasks which has been running for more than {duration} seconds
    QueryPipelineTaskAction* query_pipeline_task_action =
            _pool.add(new QueryPipelineTaskAction(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/query_pipeline_tasks/{query_id}",
                                      query_pipeline_task_action);

    // Dump all be process thread num
    BeProcThreadAction* be_proc_thread_action = _pool.add(new BeProcThreadAction(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/be_process_thread_num",
                                      be_proc_thread_action);

    // Register BE LoadStream action
    LoadStreamAction* load_stream_action = _pool.add(new LoadStreamAction(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/load_streams", load_stream_action);

    // Register Tablets Info action
    TabletsInfoAction* tablets_info_action =
            _pool.add(new TabletsInfoAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/tablets_json", tablets_info_action);

    // register pprof actions
    static_cast<void>(PprofActions::setup(_env, _ev_http_server.get(), _pool));

    // register jeprof actions
    SetJeHeapProfileActiveActions* set_jeheap_profile_active_action =
            _pool.add(new SetJeHeapProfileActiveActions(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/jeheap/active/{prof_value}",
                                      set_jeheap_profile_active_action);

    DumpJeHeapProfileToDotActions* dump_jeheap_profile_to_dot_action =
            _pool.add(new DumpJeHeapProfileToDotActions(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/jeheap/dump",
                                      dump_jeheap_profile_to_dot_action);

    DumpJeHeapProfileActions* dump_jeheap_profile_action =
            _pool.add(new DumpJeHeapProfileActions(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/jeheap/dump_only",
                                      dump_jeheap_profile_action);

    // register metrics
    {
        auto* action =
                _pool.add(new MetricsAction(DorisMetrics::instance()->metric_registry(), _env,
                                            TPrivilegeHier::GLOBAL, TPrivilegeType::NONE));
        _ev_http_server->register_handler(HttpMethod::GET, "/metrics", action);
    }

    MetaAction* meta_action =
            _pool.add(new MetaAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/meta/{op}/{tablet_id}", meta_action);

    ConfigAction* update_config_action =
            _pool.add(new ConfigAction(ConfigActionType::UPDATE_CONFIG, _env));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/update_config", update_config_action);

    ConfigAction* show_config_action =
            _pool.add(new ConfigAction(ConfigActionType::SHOW_CONFIG, _env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/show_config", show_config_action);

    // 3 check action
    CheckRPCChannelAction* check_rpc_channel_action = _pool.add(
            new CheckRPCChannelAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET,
                                      "/api/check_rpc_channel/{ip}/{port}/{payload_size}",
                                      check_rpc_channel_action);

    ResetRPCChannelAction* reset_rpc_channel_action = _pool.add(
            new ResetRPCChannelAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/reset_rpc_channel/{endpoints}",
                                      reset_rpc_channel_action);

    register_debug_point_handler();

    ReportAction* report_task_action = _pool.add(
            new ReportAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN, "REPORT_TASK"));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/report/task", report_task_action);

    // shrink memory for starting co-exist process during upgrade
    ShrinkMemAction* shrink_mem_action = _pool.add(new ShrinkMemAction(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/shrink_mem", shrink_mem_action);

#ifndef BE_TEST
    auto& engine = _env->storage_engine();
    if (config::is_cloud_mode()) {
        register_cloud_handler(engine.to_cloud());
    } else {
        register_local_handler(engine.to_local());
    }
#endif
    _ev_http_server->start();
    return Status::OK();
}
// NOLINTEND(readability-function-size)

void HttpService::register_debug_point_handler() {
    // debug point
    AddDebugPointAction* add_debug_point_action =
            _pool.add(new AddDebugPointAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/debug_point/add/{debug_point}",
                                      add_debug_point_action);

    RemoveDebugPointAction* remove_debug_point_action = _pool.add(
            new RemoveDebugPointAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/debug_point/remove/{debug_point}",
                                      remove_debug_point_action);

    ClearDebugPointsAction* clear_debug_points_action = _pool.add(
            new ClearDebugPointsAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/debug_point/clear",
                                      clear_debug_points_action);
}

// NOLINTBEGIN(readability-function-size)
void HttpService::register_local_handler(StorageEngine& engine) {
    // register download action
    std::vector<std::string> allow_paths;
    for (const auto& path : _env->store_paths()) {
        allow_paths.emplace_back(path.path);
    }
    DownloadAction* download_action = _pool.add(new DownloadAction(_env, nullptr, allow_paths));
    _ev_http_server->register_handler(HttpMethod::HEAD, "/api/_download_load", download_action);
    _ev_http_server->register_handler(HttpMethod::GET, "/api/_download_load", download_action);

    DownloadAction* tablet_download_action =
            _pool.add(new DownloadAction(_env, _rate_limit_group, allow_paths));
    _ev_http_server->register_handler(HttpMethod::HEAD, "/api/_tablet/_download",
                                      tablet_download_action);
    _ev_http_server->register_handler(HttpMethod::GET, "/api/_tablet/_download",
                                      tablet_download_action);

    BatchDownloadAction* batch_download_action =
            _pool.add(new BatchDownloadAction(_env, _rate_limit_group, allow_paths));
    _ev_http_server->register_handler(HttpMethod::HEAD, "/api/_tablet/_batch_download",
                                      batch_download_action);
    _ev_http_server->register_handler(HttpMethod::GET, "/api/_tablet/_batch_download",
                                      batch_download_action);
    _ev_http_server->register_handler(HttpMethod::POST, "/api/_tablet/_batch_download",
                                      batch_download_action);

    if (config::enable_single_replica_load) {
        DownloadAction* single_replica_download_action = _pool.add(new DownloadAction(
                _env, nullptr, allow_paths, config::single_replica_load_download_num_workers));
        _ev_http_server->register_handler(HttpMethod::HEAD, "/api/_single_replica/_download",
                                          single_replica_download_action);
        _ev_http_server->register_handler(HttpMethod::GET, "/api/_single_replica/_download",
                                          single_replica_download_action);
    }

    DownloadBinlogAction* download_binlog_action =
            _pool.add(new DownloadBinlogAction(_env, engine, _rate_limit_group));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/_binlog/_download",
                                      download_binlog_action);
    _ev_http_server->register_handler(HttpMethod::HEAD, "/api/_binlog/_download",
                                      download_binlog_action);

    FileCacheAction* file_cache_action = _pool.add(new FileCacheAction(_env));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/file_cache", file_cache_action);

    TabletsDistributionAction* tablets_distribution_action =
            _pool.add(new TabletsDistributionAction(_env, engine, TPrivilegeHier::GLOBAL,
                                                    TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/tablets_distribution",
                                      tablets_distribution_action);

    // Register tablet migration action
    TabletMigrationAction* tablet_migration_action = _pool.add(
            new TabletMigrationAction(_env, engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/tablet_migration",
                                      tablet_migration_action);

#ifndef BE_TEST
    // Register BE checksum action
    ChecksumAction* checksum_action = _pool.add(
            new ChecksumAction(_env, engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/checksum", checksum_action);

    // Register BE reload tablet action
    ReloadTabletAction* reload_tablet_action = _pool.add(
            new ReloadTabletAction(_env, engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/reload_tablet", reload_tablet_action);

    RestoreTabletAction* restore_tablet_action = _pool.add(
            new RestoreTabletAction(_env, engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/restore_tablet",
                                      restore_tablet_action);

    // Register BE snapshot action
    SnapshotAction* snapshot_action = _pool.add(
            new SnapshotAction(_env, engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/snapshot", snapshot_action);
#endif
    // 2 compaction actions
    CompactionAction* show_compaction_action =
            _pool.add(new CompactionAction(CompactionActionType::SHOW_INFO, _env, engine,
                                           TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/compaction/show",
                                      show_compaction_action);
    CompactionAction* run_compaction_action =
            _pool.add(new CompactionAction(CompactionActionType::RUN_COMPACTION, _env, engine,
                                           TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/compaction/run",
                                      run_compaction_action);
    CompactionAction* run_status_compaction_action =
            _pool.add(new CompactionAction(CompactionActionType::RUN_COMPACTION_STATUS, _env,
                                           engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));

    _ev_http_server->register_handler(HttpMethod::GET, "/api/compaction/run_status",
                                      run_status_compaction_action);

    DeleteBitmapAction* count_delete_bitmap_action =
            _pool.add(new DeleteBitmapAction(DeleteBitmapActionType::COUNT_LOCAL, _env, engine,
                                             TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/delete_bitmap/count_local",
                                      count_delete_bitmap_action);

    CheckTabletSegmentAction* check_tablet_segment_action = _pool.add(new CheckTabletSegmentAction(
            _env, engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/check_tablet_segment_lost",
                                      check_tablet_segment_action);

    PadRowsetAction* pad_rowset_action = _pool.add(
            new PadRowsetAction(_env, engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/pad_rowset", pad_rowset_action);

    ReportAction* report_tablet_action = _pool.add(new ReportAction(
            _env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN, "REPORT_OLAP_TABLET"));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/report/tablet", report_tablet_action);

    ReportAction* report_disk_action = _pool.add(new ReportAction(
            _env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN, "REPORT_DISK_STATE"));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/report/disk", report_disk_action);

    CalcFileCrcAction* calc_crc_action = _pool.add(
            new CalcFileCrcAction(_env, engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/calc_crc", calc_crc_action);

    ShowNestedIndexFileAction* show_nested_index_file_action = _pool.add(
            new ShowNestedIndexFileAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/show_nested_index_file",
                                      show_nested_index_file_action);

    CompactionScoreAction* compaction_score_action = _pool.add(new CompactionScoreAction(
            _env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN, engine.tablet_manager()));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/compaction_score",
                                      compaction_score_action);
}

void HttpService::register_cloud_handler(CloudStorageEngine& engine) {
    CloudCompactionAction* show_compaction_action =
            _pool.add(new CloudCompactionAction(CompactionActionType::SHOW_INFO, _env, engine,
                                                TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/compaction/show",
                                      show_compaction_action);
    CloudCompactionAction* run_compaction_action =
            _pool.add(new CloudCompactionAction(CompactionActionType::RUN_COMPACTION, _env, engine,
                                                TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::POST, "/api/compaction/run",
                                      run_compaction_action);
    CloudCompactionAction* run_status_compaction_action = _pool.add(
            new CloudCompactionAction(CompactionActionType::RUN_COMPACTION_STATUS, _env, engine,
                                      TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/compaction/run_status",
                                      run_status_compaction_action);
    DeleteBitmapAction* count_local_delete_bitmap_action =
            _pool.add(new DeleteBitmapAction(DeleteBitmapActionType::COUNT_LOCAL, _env, engine,
                                             TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/delete_bitmap/count_local",
                                      count_local_delete_bitmap_action);
    DeleteBitmapAction* count_ms_delete_bitmap_action =
            _pool.add(new DeleteBitmapAction(DeleteBitmapActionType::COUNT_MS, _env, engine,
                                             TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/delete_bitmap/count_ms",
                                      count_ms_delete_bitmap_action);
#ifdef ENABLE_INJECTION_POINT
    InjectionPointAction* injection_point_action = _pool.add(new InjectionPointAction);
    _ev_http_server->register_handler(HttpMethod::GET, "/api/injection_point/{op}",
                                      injection_point_action);
#endif
    FileCacheAction* file_cache_action = _pool.add(new FileCacheAction(_env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/file_cache", file_cache_action);
    auto* show_hotspot_action = _pool.add(new ShowHotspotAction(engine, _env));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/hotspot/tablet", show_hotspot_action);

    CalcFileCrcAction* calc_crc_action = _pool.add(
            new CalcFileCrcAction(_env, engine, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/calc_crc", calc_crc_action);

    ShowNestedIndexFileAction* show_nested_index_file_action = _pool.add(
            new ShowNestedIndexFileAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/show_nested_index_file",
                                      show_nested_index_file_action);
    CompactionScoreAction* compaction_score_action = _pool.add(new CompactionScoreAction(
            _env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN, engine.tablet_mgr()));
    _ev_http_server->register_handler(HttpMethod::GET, "/api/compaction_score",
                                      compaction_score_action);
}
// NOLINTEND(readability-function-size)

void HttpService::stop() {
    if (stopped) {
        return;
    }
    _ev_http_server->stop();
    _pool.clear();
    stopped = true;
}

int HttpService::get_real_port() const {
    return _ev_http_server->get_real_port();
}

#include "common/compile_check_end.h"
} // namespace doris
