/*
 * 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 <malloc.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) {
        if (mPid != pid_all) {
            asprintf(strp, "%u/%u", mUid, mPid);
        } else {
            asprintf(strp, "%u", mUid);
        }
    } else if (mPid != pid_all) {
        asprintf(strp, "/%u", mPid);
    } else { // NB: mPid == pid_all can not happen if mUid == uid_all
        asprintf(strp, "/");
    }
}

PruneList::PruneList()
        : mWorstUidEnabled(false) {
    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 = false;
    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;
}
