// 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 "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
