// Copyright 2024 Google Inc. All Rights Reserved.
//
// 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 NINJA_STATUS_PRINTER_H_
#define NINJA_STATUS_PRINTER_H_

#include <memory>
#include <unordered_map>
#include <vector>

#include "async_loop.h"
#include "build.h"
#include "line_printer.h"
#include "status.h"

/// Implementation of the Status interface that prints the status as
/// human-readable strings to stdout
struct StatusPrinter : Status {
  explicit StatusPrinter(const BuildConfig& config);
  void PlanHasTotalEdges(int total) override;
  void BuildEdgeStarted(const Edge* edge) override;
  void BuildEdgeFinished(Edge* edge, bool success,
                         const std::string& output) override;
  void BuildLoadDyndeps() override;
  void BuildStarted() override;
  void BuildFinished() override;

  void Info(const char* msg, ...) override;
  void Warning(const char* msg, ...) override;
  void Error(const char* msg, ...) override;

  virtual ~StatusPrinter();

  /// Format the progress status string by replacing the placeholders.
  /// See the user manual for more information about the available
  /// placeholders.
  /// @param progress_status_format The format of the progress status.
  /// @param status The status of the edge.
  std::string FormatProgressStatus(const char* progress_status_format,
                                   int64_t time_millis) const;

 private:
  void PrintStatus(const Edge* edge, int64_t time_millis);

  void BuildRefresh(int64_t current_time_ms);
  void EnableTimer();
  void DisableTimer();

  int64_t GetCurrentBuildTimeMs() const;

  const BuildConfig& config_;

  int started_edges_, finished_edges_, total_edges_, running_edges_;
  int64_t time_millis_;

  /// Prints progress output.
  LinePrinter printer_;

  struct SlidingRateInfo {
    SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {}

    double rate() { return rate_; }

    void UpdateRate(int update_hint, int64_t time_millis) {
      if (update_hint == last_update_)
        return;
      last_update_ = update_hint;

      if (times_.size() == N)
        times_.pop();
      times_.push(time_millis);
      if (times_.back() != times_.front())
        rate_ = times_.size() / ((times_.back() - times_.front()) / 1e3);
    }

   private:
    double rate_;
    const size_t N;
    std::queue<double> times_;
    int last_update_;
  };

  /// Called to refresh the pending list if needed.
  void BuildRefresh();

  mutable SlidingRateInfo current_rate_;

  /// Support for printing pending edges below the status on smart terminals.
  void PrintPendingEdges(int64_t cur_time_millis);
  void ClearPendingEdges();

  std::string format_;
  int64_t refresh_timeout_ms_ = -1;
  size_t max_pending_height_ = 0;
  size_t last_pending_height_ = 0;
  int64_t start_build_time_ms_ = 0;
  int64_t last_update_time_ms_ = -1;
  std::string last_status_;

  AsyncLoop& async_loop_;
  AsyncTimer timer_;

  // Record pending edges
  using EdgeMap = std::unordered_map<const Edge*, int64_t>;
  EdgeMap pending_edges_;

  // Used on each PrintPendingEdges() call to minimize heap allocations.
  // Note that EdgeMap::value_type.first has type |const Edge* const| and
  // thus EdgeMap::value_type is not copyable and cannot be used as an
  // std::vector<> item type.
  using EdgeInfo = std::pair<const Edge*, int64_t>;
  std::vector<EdgeInfo> sorted_pending_edges_;
};

#endif  // NINJA_STATUS_PRINTER_H_
