// Copyright 2024 Bloomberg Finance L.P
//
// Licensed 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.

#ifndef INCLUDED_RUMBAD_SHAREDMEMORY
#define INCLUDED_RUMBAD_SHAREDMEMORY

#include <buildboxcommon_fileutils.h>
#include <chrono>
#include <string>

#include <rumbad_writer.h>

static const std::string COUNTER_NAME_ACTION_CACHE_HIT =
    "recc.action_cache_hit";
static const std::string COUNTER_NAME_ACTION_CACHE_MISS =
    "recc.action_cache_miss";
static const std::string COUNTER_NAME_ACTION_CACHE_SKIP =
    "recc.action_cache_skip";
static const std::string COUNTER_NAME_LINK_ACTION_CACHE_HIT =
    "recc.link_action_cache_hit";
static const std::string COUNTER_NAME_LINK_ACTION_CACHE_MISS =
    "recc.link_action_cache_miss";
static const std::string COUNTER_NAME_UPLOAD_BLOBS_CACHE_HIT =
    "recc.upload_blobs_cache_hit";
static const std::string COUNTER_NAME_UPLOAD_BLOBS_CACHE_MISS =
    "recc.upload_blobs_cache_miss";
static const std::string COUNTER_NAME_INPUT_SIZE_BYTES =
    "recc.input_size_bytes";
static const std::string COUNTER_NAME_UNSUPPORTED_COMMAND =
    "recc.unsupported_command";

namespace rumbad {
struct StatsData {
    std::chrono::time_point<std::chrono::system_clock> updated_at =
        std::chrono::system_clock::now();
    int d_compile_command_counts = 0;
    int d_compile_command_cache_hit_counts = 0;
    int d_compile_command_cache_skip_counts = 0;
    int d_linking_command_counts = 0;
    int d_linking_command_cache_hit_counts = 0;
};

class StatsManager {
  public:
    StatsManager();

    // Setters
    void setStatsFilepath(const std::string &filepath);
    void incrementCompileCommandCounts(int count = 1);
    void incrementCompileCommandCacheHitCounts(int count = 1);
    void incrementCompileCommandCacheSkipCounts(int count = 1);
    void incrementLinkingCommandCounts(int count = 1);
    void incrementLinkingCommandCacheHitCounts(int count = 1);

    // Getters
    int totalCommandCounts();
    float compileCacheHitRate();
    float linkCacheHitRate();
    StatsData const *readonlyStatsdata();
    std::map<std::string, std::string> statsdataMap();
    std::string outputString();
    std::string statsFilepath();

    // Helpers
    void updateStatsInBatch(const std::vector<Message> &batch);
    void updateStats(const Message &message);
    bool saveFilepathIsSet();
    int saveStatsToFile();
    int saveStatsToFile(const std::string &filepath);

  private:
    StatsData *d_statsdata;
    StatsData d_statsdata_storage;
    std::string d_statsFilepath;
};
} // namespace rumbad

#endif
