// Copyright 2015 The Crashpad Authors
//
// 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.

#include "client/prune_crash_reports.h"

#include <sys/stat.h>
#include <stdint.h>

#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "base/notreached.h"
#include "build/build_config.h"

namespace crashpad {

size_t PruneCrashReportDatabase(CrashReportDatabase* database,
                              PruneCondition* condition) {
  std::vector<CrashReportDatabase::Report> all_reports;
  CrashReportDatabase::OperationStatus status;

  status = database->GetPendingReports(&all_reports);
  if (status != CrashReportDatabase::kNoError) {
    LOG(ERROR) << "PruneCrashReportDatabase: Failed to get pending reports";
    return 0;
  }

  std::vector<CrashReportDatabase::Report> completed_reports;
  status = database->GetCompletedReports(&completed_reports);
  if (status != CrashReportDatabase::kNoError) {
    LOG(ERROR) << "PruneCrashReportDatabase: Failed to get completed reports";
    return 0;
  }
  all_reports.insert(all_reports.end(), completed_reports.begin(),
                     completed_reports.end());

  std::sort(all_reports.begin(), all_reports.end(),
      [](const CrashReportDatabase::Report& lhs,
         const CrashReportDatabase::Report& rhs) {
        return lhs.creation_time > rhs.creation_time;
      });

  size_t num_pruned = 0;
  for (const auto& report : all_reports) {
    if (condition->ShouldPruneReport(report)) {
      status = database->DeleteReport(report.uuid);
      if (status != CrashReportDatabase::kNoError) {
        LOG(ERROR) << "Database Pruning: Failed to remove report "
                   << report.uuid.ToString();
      } else {
        num_pruned++;
      }
    }
  }

  return num_pruned;

  // TODO(rsesek): For databases that do not use a directory structure, it is
  // possible for the metadata sidecar to become corrupted and thus leave
  // orphaned crash report files on-disk. https://crashpad.chromium.org/bug/66
}

// static
std::unique_ptr<PruneCondition> PruneCondition::GetDefault() {
  // DatabaseSizePruneCondition must be the LHS so that it is always evaluated,
  // due to the short-circuting behavior of BinaryPruneCondition.
  return std::make_unique<BinaryPruneCondition>(
      BinaryPruneCondition::OR,
      new DatabaseSizePruneCondition(1024 * 128),
      new AgePruneCondition(365));
}

static const time_t kSecondsInDay = 60 * 60 * 24;

AgePruneCondition::AgePruneCondition(int max_age_in_days)
    : oldest_report_time_(
        ((time(nullptr) - (max_age_in_days * kSecondsInDay))
             / kSecondsInDay) * kSecondsInDay) {}

AgePruneCondition::~AgePruneCondition() {}

bool AgePruneCondition::ShouldPruneReport(
    const CrashReportDatabase::Report& report) {
  return report.creation_time < oldest_report_time_;
}

DatabaseSizePruneCondition::DatabaseSizePruneCondition(size_t max_size_in_kb)
    : max_size_in_kb_(max_size_in_kb), measured_size_in_kb_(0) {}

DatabaseSizePruneCondition::~DatabaseSizePruneCondition() {}

bool DatabaseSizePruneCondition::ShouldPruneReport(
    const CrashReportDatabase::Report& report) {
  // Round up fractional KB to the next 1-KB boundary.
  measured_size_in_kb_ +=
      static_cast<size_t>((report.total_size + 1023) / 1024);
  return measured_size_in_kb_ > max_size_in_kb_;
}

BinaryPruneCondition::BinaryPruneCondition(
    Operator op, PruneCondition* lhs, PruneCondition* rhs)
    : op_(op), lhs_(lhs), rhs_(rhs) {}

BinaryPruneCondition::~BinaryPruneCondition() {}

bool BinaryPruneCondition::ShouldPruneReport(
    const CrashReportDatabase::Report& report) {
  switch (op_) {
    case AND:
      return lhs_->ShouldPruneReport(report) && rhs_->ShouldPruneReport(report);
    case OR:
      return lhs_->ShouldPruneReport(report) || rhs_->ShouldPruneReport(report);
    default:
      NOTREACHED();
      return false;
  }
}

}  // namespace crashpad
