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

#include "client/prune_crash_reports.h"

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

#include <algorithm>
#include <vector>

#include "base/logging.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
