// Copyright 2016 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

#include "android/metrics/FileMetricsWriter.h"

#include "android/base/files/PathUtils.h"
#include "android/base/Log.h"
#include "android/base/StringFormat.h"
#include "android/base/Uuid.h"
#include "android/metrics/MetricsLogging.h"
#include "android/protobuf/DelimitedSerialization.h"
#include "android/utils/eintr_wrapper.h"
#include "android/utils/path.h"

#include "android/metrics/proto/clientanalytics.pb.h"

#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

using android::base::AutoLock;
using android::base::Looper;
using android::base::makeCustomScopedPtr;
using android::base::PathUtils;
using android::base::System;
using android::base::StringView;
using android::base::StringFormat;
using android::base::Uuid;

namespace android {
namespace metrics {

// Only Windows has a No-inherit open() flag, and only Windows cares about
// difference between binary/text files.
#ifdef _WIN32
static constexpr int kCommonOpenFlags = O_BINARY | O_NOINHERIT;
#else
static constexpr int kCommonOpenFlags = 0;
#endif

// Extensions for an active temporary logging file and for the finalized one.
static constexpr StringView kTempExtension = ".open";
static constexpr StringView kFinalExtension = ".trx";

// A limit for a counter appended to the log filename to enable multiple files
// with the same session ID.
static constexpr int kMaxFilenameCounter = 1000000;
// Number of retries for a failed file operation, e.g. open(), rename(), etc.
static constexpr int kMaxFileOperationTries = 1000;

// Create a log filename with the passed |sessionId|, |counter| and |extension|.
static std::string formatFilename(StringView sessionId,
                                  int counter,
                                  StringView extension) {
    return StringFormat("emulator-metrics-%s-%d-%d%s", sessionId,
                        (int)System::get()->getCurrentProcessId(), counter,
                        extension);
}

// A cross-platform function to rename an |from| file to |to| name only if |to|
// doesn't exist.
// On POSIX one needs to make sure the |to| doesn't exist, otherwise it will be
// owerwritten. On Windows rename() never overwrites target.
static bool renameIfNotExists(StringView from, StringView to) {
#ifdef _WIN32
    return rename(from.c_str(), to.c_str()) == 0;
#else
    if (System::get()->pathExists(to)) {
        return false;
    }
    // There's a small chance of race condition here, but we don't actually
    // rename files in several threads, so it's OK.
    // TODO(zyy): use renameat2() on Linux to make it atomic.
    if (HANDLE_EINTR(rename(from.c_str(), to.c_str())) != 0) {
        return false;
    }
    return true;
#endif
}

FileMetricsWriter::FileMetricsWriter(StringView spoolDir,
                                     const std::string& sessionId,
                                     int recordCountLimit,
                                     Looper* looper,
                                     System::Duration timeLimitMs)
    : MetricsWriter(sessionId),
      mSpoolDir(spoolDir),
      mTimeLimitMs(timeLimitMs),
      mRecordCountLimit(recordCountLimit),
      mLooper(looper),
      mActiveFileLock(
          makeCustomScopedPtr<FileLock*>(nullptr, filelock_release)) {
    D("created a FileMetricsWriter");
    assert(strlen(spoolDir.data()) == spoolDir.size());
    path_mkdir_if_needed(spoolDir.data(), 0744);
    assert(System::get()->pathIsDir(spoolDir));

    // It's OK to call this without a lock in ctor - there's no external
    // references to the object yet.
    openNewFileNoLock();
}

FileMetricsWriter::Ptr FileMetricsWriter::create(StringView spoolDir,
                                                 const std::string& sessionId,
                                                 int recordCountLimit,
                                                 Looper* looper,
                                                 System::Duration timeLimitMs) {
    return Ptr(new FileMetricsWriter(spoolDir, sessionId, recordCountLimit,
                                     looper, timeLimitMs));
}

MetricsWriter::AbandonedSessions
FileMetricsWriter::finalizeAbandonedSessionFiles(StringView spoolDir) {
    AbandonedSessions abandonedSessions;
    const std::vector<std::string> files =
            System::get()->scanDirEntries(spoolDir);
    for (const std::string& file : files) {
        if (PathUtils::extension(file) != kTempExtension) {
            continue;
        }

        // try to lock the file to find out if it's abandoned
        const auto lock = makeCustomScopedPtr(
                filelock_create(PathUtils::join(spoolDir, file).c_str()),
                filelock_release);
        if (!lock) {
            continue;
        }

        // parse the file name to get session ID and the filename counter
        int filenameCounter = 0;
        std::string sessionId = Uuid::nullUuidStr;
        assert(sessionId.size() >= 36);
        int scanned = sscanf(file.c_str(), "emulator-metrics-%36s-%*d-%d",
                             &sessionId[0], &filenameCounter);
        assert(scanned == 2);
        (void)scanned;

        // now rename it
        if (!runFileOperationWithRetries(&filenameCounter, [spoolDir,
                                                            &sessionId,
                                                            &filenameCounter,
                                                            &file]() -> bool {
                const std::string finalName = PathUtils::join(
                        spoolDir, formatFilename(sessionId, filenameCounter,
                                                 kFinalExtension));
                return renameIfNotExists(PathUtils::join(spoolDir, file),
                                         finalName);
            })) {
            W("failed to rename an abandoned log file '%s'", file.c_str());
        }

        abandonedSessions.insert(std::move(sessionId));
    }

    return abandonedSessions;
}

FileMetricsWriter::~FileMetricsWriter() {
    AutoLock lock(mLock);
    if (mTimer) {
        mTimer->stop();
        mTimer.reset();
    }
    finalizeActiveFileNoLock();
}

void FileMetricsWriter::finalizeActiveFileNoLock() {
    if (!mActiveFile) {
        return;
    }

    mActiveFile.reset();
    if (!runFileOperationWithRetries(&mFilenameCounter, [this]() -> bool {
            const std::string finalName = PathUtils::join(
                    mSpoolDir, formatFilename(sessionId(), mFilenameCounter,
                                              kFinalExtension));
            return renameIfNotExists(mActiveFileName, finalName);
        })) {
        W("failed to rename an active log file '%s'", mActiveFileName.c_str());
    } else {
        D("finalized active log file '%s'", mActiveFileName.c_str());
    }
    mActiveFileLock.reset();
    mActiveFileName.clear();
    mRecordCount = 0;
    // We've done with the current file no, make sure the next one gets a
    // new counter value.
    advanceFilenameCounter(&mFilenameCounter);
}

void FileMetricsWriter::openNewFileNoLock() {
    std::string newName;
    int fd = -1;
    if (!runFileOperationWithRetries(&mFilenameCounter, [this, &newName,
                                                         &fd]() -> bool {
            std::string testName = PathUtils::join(
                    mSpoolDir, formatFilename(sessionId(), mFilenameCounter,
                                              kTempExtension));

            mActiveFileLock.reset(filelock_create(testName.c_str()));
            if (!mActiveFileLock) {
                return false;
            }
            const int testFd = HANDLE_EINTR(
                    open(testName.c_str(),
                         O_WRONLY | O_CREAT | O_EXCL | kCommonOpenFlags,
                         S_IREAD | S_IWRITE));
            if (testFd < 0) {
                mActiveFileLock.reset();
                return false;
            }
            newName = std::move(testName);
            fd = testFd;
            return true;
        })) {
        W("failed to open a new log file");
        return;
    }

    assert(fd >= 0);
    assert(!newName.empty());

    mActiveFile.reset(new google::protobuf::io::FileOutputStream(fd));
    if (!mActiveFile) {
        E("memory allocation failed");
        close(fd);
        HANDLE_EINTR(unlink(newName.c_str()));
        return;
    }
    mActiveFile->SetCloseOnDelete(true);
    mActiveFileName = std::move(newName);
    mRecordCount = 0;

    D("opened new metrics file %s", mActiveFileName.c_str());
}

bool FileMetricsWriter::countLimitReached() const {
    // Only check the count limit if there is one.
    return mRecordCountLimit > 0 && mRecordCount >= mRecordCountLimit;
}

void FileMetricsWriter::advanceFilenameCounter(int* counter) {
    *counter = (*counter + 1) % kMaxFilenameCounter;
}

void FileMetricsWriter::ensureTimerStarted() {
    if (mTimer || mTimeLimitMs <= 0 || !mLooper) {
        return;
    }

    mTimer.reset(mLooper->createTimer(
            [](void* weakSelf, Looper::Timer* timer) {
                auto weakPtr =
                        static_cast<FileMetricsWriter::WPtr*>(weakSelf);
                if (auto ptr = weakPtr->lock()) {
                    ptr->onTimer();
                } else {
                    delete weakPtr;  // we're done
                }
            },
            new WPtr(shared_from_this())));
    if (mTimer) {
        mTimer->startRelative(mTimeLimitMs);

        D("started metrics timer with a period of %d ms",
          mTimeLimitMs);
    }
}

void FileMetricsWriter::onTimer() {
    D("timer tick");

    AutoLock lock(mLock);
    if (mRecordCount > 0) {
        finalizeActiveFileNoLock();
        openNewFileNoLock();
    }

    mTimer->startRelative(mTimeLimitMs);
}

template <class Operation>
bool FileMetricsWriter::runFileOperationWithRetries(int* filenameCounter,
                                                    Operation op) {
    for (int i = 0; i < kMaxFileOperationTries;
         ++i, advanceFilenameCounter(filenameCounter)) {
        if (op()) {
            return true;
        }
    }

    return false;
}

void FileMetricsWriter::write(
        const wireless_android_play_playlog::LogEvent& event) {
    D("writing a log event with uptime %ld ms", event.event_uptime_ms());

    AutoLock lock(mLock);

    if (!mActiveFile) {
        openNewFileNoLock();
    }
    if (!mActiveFile) {
        W("No active log file during write(), event lost:\n%s",
          event.DebugString().c_str());
        return;
    }
    ensureTimerStarted();

    protobuf::writeOneDelimited(event, mActiveFile.get());
    // FileOutputStream buffers everything it can, but it means we may lose
    // a message on a crash, so let's just flush it every time.
    // Shouldn't affect performance as it's expected that only asynchronous
    // metrics reporter is used in the emulator process.
    mActiveFile->Flush();
    ++mRecordCount;

    if (countLimitReached()) {
        finalizeActiveFileNoLock();
        openNewFileNoLock();
    }
}

}  // namespace metrics
}  // namespace android
