/*
 * Copyright (C) 2014 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 <ctype.h>

#include <utils/String8.h>

#include "LogWhiteBlackList.h"

// White and Black list

Prune::Prune(uid_t uid, pid_t pid)
        : mUid(uid)
        , mPid(pid)
{ }

int Prune::cmp(uid_t uid, pid_t pid) const {
    if ((mUid == uid_all) || (mUid == uid)) {
        if (mPid == pid_all) {
            return 0;
        }
        return pid - mPid;
    }
    return uid - mUid;
}

void Prune::format(char **strp) {
    if (mUid != uid_all) {
        asprintf(strp, (mPid != pid_all) ? "%u/%u" : "%u", mUid, mPid);
    } else {
        // NB: mPid == pid_all can not happen if mUid == uid_all
        asprintf(strp, (mPid != pid_all) ? "/%u" : "/", mPid);
    }
}

PruneList::PruneList()
        : mWorstUidEnabled(true) {
    mNaughty.clear();
    mNice.clear();
}

PruneList::~PruneList() {
    PruneCollection::iterator it;
    for (it = mNice.begin(); it != mNice.end();) {
        delete (*it);
        it = mNice.erase(it);
    }
    for (it = mNaughty.begin(); it != mNaughty.end();) {
        delete (*it);
        it = mNaughty.erase(it);
    }
}

int PruneList::init(char *str) {
    mWorstUidEnabled = true;
    PruneCollection::iterator it;
    for (it = mNice.begin(); it != mNice.end();) {
        delete (*it);
        it = mNice.erase(it);
    }
    for (it = mNaughty.begin(); it != mNaughty.end();) {
        delete (*it);
        it = mNaughty.erase(it);
    }

    if (!str) {
        return 0;
    }

    mWorstUidEnabled = false;

    for(; *str; ++str) {
        if (isspace(*str)) {
            continue;
        }

        PruneCollection *list;
        if ((*str == '~') || (*str == '!')) { // ~ supported, ! undocumented
            ++str;
            // special case, translates to worst UID at priority in blacklist
            if (*str == '!') {
                mWorstUidEnabled = true;
                ++str;
                if (!*str) {
                    break;
                }
                if (!isspace(*str)) {
                    return 1;
                }
                continue;
            }
            if (!*str) {
                return 1;
            }
            list = &mNaughty;
        } else {
            list = &mNice;
        }

        uid_t uid = Prune::uid_all;
        if (isdigit(*str)) {
            uid = 0;
            do {
                uid = uid * 10 + *str++ - '0';
            } while (isdigit(*str));
        }

        pid_t pid = Prune::pid_all;
        if (*str == '/') {
            ++str;
            if (isdigit(*str)) {
                pid = 0;
                do {
                    pid = pid * 10 + *str++ - '0';
                } while (isdigit(*str));
            }
        }

        if ((uid == Prune::uid_all) && (pid == Prune::pid_all)) {
            return 1;
        }

        if (*str && !isspace(*str)) {
            return 1;
        }

        // insert sequentially into list
        PruneCollection::iterator it = list->begin();
        while (it != list->end()) {
            Prune *p = *it;
            int m = uid - p->mUid;
            if (m == 0) {
                if (p->mPid == p->pid_all) {
                    break;
                }
                if ((pid == p->pid_all) && (p->mPid != p->pid_all)) {
                    it = list->erase(it);
                    continue;
                }
                m = pid - p->mPid;
            }
            if (m <= 0) {
                if (m < 0) {
                    list->insert(it, new Prune(uid,pid));
                }
                break;
            }
            ++it;
        }
        if (it == list->end()) {
            list->push_back(new Prune(uid,pid));
        }
        if (!*str) {
            break;
        }
    }

    return 0;
}

void PruneList::format(char **strp) {
    if (*strp) {
        free(*strp);
        *strp = NULL;
    }

    static const char nice_format[] = " %s";
    const char *fmt = nice_format + 1;

    android::String8 string;

    if (mWorstUidEnabled) {
        string.setTo("~!");
        fmt = nice_format;
    }

    PruneCollection::iterator it;

    for (it = mNice.begin(); it != mNice.end(); ++it) {
        char *a = NULL;
        (*it)->format(&a);

        string.appendFormat(fmt, a);
        fmt = nice_format;

        free(a);
    }

    static const char naughty_format[] = " ~%s";
    fmt = naughty_format + (*fmt != ' ');
    for (it = mNaughty.begin(); it != mNaughty.end(); ++it) {
        char *a = NULL;
        (*it)->format(&a);

        string.appendFormat(fmt, a);
        fmt = naughty_format;

        free(a);
    }

    *strp = strdup(string.string());
}

// ToDo: Lists are in sorted order, Prune->cmp() returns + or -
// If there is scaling issues, resort to a better algorithm than linear
// based on these assumptions.

bool PruneList::naughty(LogBufferElement *element) {
    PruneCollection::iterator it;
    for (it = mNaughty.begin(); it != mNaughty.end(); ++it) {
        if (!(*it)->cmp(element)) {
            return true;
        }
    }
    return false;
}

bool PruneList::nice(LogBufferElement *element) {
    PruneCollection::iterator it;
    for (it = mNice.begin(); it != mNice.end(); ++it) {
        if (!(*it)->cmp(element)) {
            return true;
        }
    }
    return false;
}
