//
// Copyright (C) 2020 The Android Open Source Project
//
// 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 <inttypes.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#include <algorithm>
#include <functional>
#include <iomanip>
#include <string>
#include <string_view>
#include <vector>

#include <android-base/file.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <base/files/dir_reader_posix.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <log/log.h>

#include "update_engine/common/utils.h"

using std::string;

namespace chromeos_update_engine {
namespace {

constexpr char kSystemLogsRoot[] = "/data/misc/update_engine_log";
constexpr size_t kLogCount = 5;

// Keep the most recent |kLogCount| logs but remove the old ones in
// "/data/misc/update_engine_log/".
void DeleteOldLogs(const string& kLogsRoot) {
  base::DirReaderPosix reader(kLogsRoot.c_str());
  if (!reader.IsValid()) {
    LOG(ERROR) << "Failed to read " << kLogsRoot;
    return;
  }

  std::vector<string> old_logs;
  while (reader.Next()) {
    if (reader.name()[0] == '.')
      continue;

    // Log files are in format "update_engine.%Y%m%d-%H%M%S",
    // e.g. update_engine.20090103-231425
    uint64_t date;
    uint64_t local_time;
    if (sscanf(reader.name(),
               "update_engine.%" PRIu64 "-%" PRIu64 "",
               &date,
               &local_time) == 2) {
      old_logs.push_back(reader.name());
    } else {
      LOG(WARNING) << "Unrecognized log file " << reader.name();
    }
  }

  std::sort(old_logs.begin(), old_logs.end(), std::greater<string>());
  for (size_t i = kLogCount; i < old_logs.size(); i++) {
    string log_path = kLogsRoot + "/" + old_logs[i];
    if (unlink(log_path.c_str()) == -1) {
      PLOG(WARNING) << "Failed to unlink " << log_path;
    }
  }
}

string SetupLogFile(const string& kLogsRoot) {
  DeleteOldLogs(kLogsRoot);

  return base::StringPrintf("%s/update_engine.%s",
                            kLogsRoot.c_str(),
                            utils::GetTimeAsString(::time(nullptr)).c_str());
}

const char* LogPriorityToCString(int priority) {
  switch (priority) {
    case ANDROID_LOG_VERBOSE:
      return "VERBOSE";
    case ANDROID_LOG_DEBUG:
      return "DEBUG";
    case ANDROID_LOG_INFO:
      return "INFO";
    case ANDROID_LOG_WARN:
      return "WARN";
    case ANDROID_LOG_ERROR:
      return "ERROR";
    case ANDROID_LOG_FATAL:
      return "FATAL";
    default:
      return "UNKNOWN";
  }
}

using LoggerFunction = std::function<void(const struct __android_log_message*)>;

class FileLogger {
 public:
  explicit FileLogger(const string& path) {
    fd_.reset(TEMP_FAILURE_RETRY(
        open(path.c_str(),
             O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_SYNC,
             0644)));
    if (fd_ == -1) {
      // Use ALOGE that logs to logd before __android_log_set_logger.
      ALOGE("Cannot open persistent log %s: %s", path.c_str(), strerror(errno));
      return;
    }
    // The log file will have AID_LOG as group ID; this GID is inherited from
    // the parent directory "/data/misc/update_engine_log" which sets the SGID
    // bit.
    if (fchmod(fd_.get(), 0640) == -1) {
      // Use ALOGE that logs to logd before __android_log_set_logger.
      ALOGE("Cannot chmod 0640 persistent log %s: %s",
            path.c_str(),
            strerror(errno));
      return;
    }
  }
  // Copy-constructor needed to be converted to std::function.
  FileLogger(const FileLogger& other) { fd_.reset(dup(other.fd_)); }
  void operator()(const struct __android_log_message* log_message) {
    if (fd_ == -1) {
      return;
    }

    // libchrome add a newline character to |message|. Strip it.
    std::string_view message_no_newline =
        log_message->message != nullptr ? log_message->message : "";
    ignore_result(android::base::ConsumeSuffix(&message_no_newline, "\n"));

    WriteToFd(GetPrefix(log_message));
    WriteToFd(message_no_newline);
    WriteToFd("\n");
  }

 private:
  android::base::unique_fd fd_;
  void WriteToFd(std::string_view message) {
    ignore_result(
        android::base::WriteFully(fd_, message.data(), message.size()));
  }

  string GetPrefix(const struct __android_log_message* log_message) {
    std::stringstream ss;
    timeval tv;
    gettimeofday(&tv, nullptr);
    time_t t = tv.tv_sec;
    struct tm local_time;
    localtime_r(&t, &local_time);
    struct tm* tm_time = &local_time;
    ss << "[" << std::setfill('0') << std::setw(2) << 1 + tm_time->tm_mon
       << std::setw(2) << tm_time->tm_mday << '/' << std::setw(2)
       << tm_time->tm_hour << std::setw(2) << tm_time->tm_min << std::setw(2)
       << tm_time->tm_sec << '.' << std::setw(6) << tv.tv_usec << "] ";
    // libchrome logs prepends |message| with severity, file and line, but
    // leave logger_data->file as nullptr.
    // libbase / liblog logs doesn't. Hence, add them to match the style.
    // For liblog logs that doesn't set logger_data->file, not printing the
    // priority is acceptable.
    if (log_message->file) {
      ss << "[" << LogPriorityToCString(log_message->priority) << ':'
         << log_message->file << '(' << log_message->line << ")] ";
    }
    return ss.str();
  }
};

class CombinedLogger {
 public:
  CombinedLogger(bool log_to_system, bool log_to_file) {
    if (log_to_system) {
      loggers_.push_back(__android_log_logd_logger);
    }
    if (log_to_file) {
      loggers_.push_back(std::move(FileLogger(SetupLogFile(kSystemLogsRoot))));
    }
  }
  void operator()(const struct __android_log_message* log_message) {
    for (auto&& logger : loggers_) {
      logger(log_message);
    }
  }

 private:
  std::vector<LoggerFunction> loggers_;
};

}  // namespace

void SetupLogging(bool log_to_system, bool log_to_file) {
  // Note that libchrome logging uses liblog.
  // By calling liblog's __android_log_set_logger function, all of libchrome
  // (used by update_engine) / libbase / liblog (used by depended modules)
  // logging eventually redirects to CombinedLogger.
  static auto g_logger =
      std::make_unique<CombinedLogger>(log_to_system, log_to_file);
  __android_log_set_logger([](const struct __android_log_message* log_message) {
    (*g_logger)(log_message);
  });

  // libchrome logging should not log to file.
  logging::LoggingSettings log_settings;
  log_settings.lock_log = logging::DONT_LOCK_LOG_FILE;
  log_settings.logging_dest = static_cast<logging::LoggingDestination>(
      logging::LOG_TO_SYSTEM_DEBUG_LOG);
  log_settings.log_file = nullptr;
  logging::InitLogging(log_settings);
  logging::SetLogItems(false /* enable_process_id */,
                       false /* enable_thread_id */,
                       false /* enable_timestamp */,
                       false /* enable_tickcount */);
}

}  // namespace chromeos_update_engine
