/*
 * Copyright (C) 2016 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.
 */
#define DEBUG false
#include "Log.h"

#include "report_directory.h"

#include <private/android_filesystem_config.h>
#include <utils/String8.h>

#include <dirent.h>
#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <vector>

namespace android {
namespace os {
namespace incidentd {

static bool stat_mtime_cmp(const std::pair<String8, struct stat>& a,
                           const std::pair<String8, struct stat>& b) {
    return a.second.st_mtime < b.second.st_mtime;
}

void clean_directory(const char* directory, off_t maxSize, size_t maxCount) {
    DIR* dir;
    struct dirent* entry;
    struct stat st;

    std::vector<std::pair<String8, struct stat>> files;

    if ((dir = opendir(directory)) == NULL) {
        ALOGE("Couldn't open incident directory: %s", directory);
        return;
    }

    String8 dirbase(directory);
    if (directory[dirbase.size() - 1] != '/') dirbase += "/";

    off_t totalSize = 0;
    size_t totalCount = 0;

    // Enumerate, count and add up size
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_name[0] == '.') {
            continue;
        }
        String8 filename = dirbase + entry->d_name;
        if (stat(filename.string(), &st) != 0) {
            ALOGE("Unable to stat file %s", filename.string());
            continue;
        }
        if (!S_ISREG(st.st_mode)) {
            continue;
        }
        files.push_back(std::pair<String8, struct stat>(filename, st));

        totalSize += st.st_size;
        totalCount++;
    }

    closedir(dir);

    // Count or size is less than max, then we're done.
    if (totalSize < maxSize && totalCount < maxCount) {
        return;
    }

    // Oldest files first.
    sort(files.begin(), files.end(), stat_mtime_cmp);

    // Remove files until we're under our limits.
    for (std::vector<std::pair<String8, struct stat>>::iterator it = files.begin();
         it != files.end() && totalSize >= maxSize && totalCount >= maxCount; it++) {
        remove(it->first.string());
        totalSize -= it->second.st_size;
        totalCount--;
    }
}

}  // namespace incidentd
}  // namespace os
}  // namespace android
