/*
 * Copyright (C) 2017 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 "KernelConfigParser.h"

#include <regex>

#define KEY "(CONFIG[\\w_]+)"
#define COMMENT "(?:#.*)"

static const std::regex sKeyValuePattern("^\\s*" KEY "\\s*=\\s*([^#]+)" COMMENT "?$");
static const std::regex sNotSetPattern("^\\s*#\\s*" KEY " is not set\\s*$");
static const std::regex sCommentPattern("^\\s*" COMMENT "$");

namespace android {
namespace vintf {

KernelConfigParser::KernelConfigParser(bool processComments, bool relaxedFormat)
    : mProcessComments(processComments), mRelaxedFormat(relaxedFormat) {}

status_t KernelConfigParser::finish() {
    return process("\n", 1 /* sizeof "\n" */);
}

std::stringbuf* KernelConfigParser::error() const {
    return mError.rdbuf();
}

std::map<std::string, std::string>& KernelConfigParser::configs() {
    return mConfigs;
}

const std::map<std::string, std::string>& KernelConfigParser::configs() const {
    return mConfigs;
}

// trim spaces between value and #, value and end of line
std::string trimTrailingSpaces(const std::string& s) {
    auto r = s.rbegin();
    for (; r != s.rend() && std::isspace(*r); ++r)
        ;
    return std::string{s.begin(), r.base()};
}

status_t KernelConfigParser::processRemaining() {

    if (mRemaining.empty()) {
        return OK;
    }

    std::smatch match;

    if (mRelaxedFormat) {
        // Allow free format like "   CONFIG_FOO  = bar    #trailing comments"
        if (std::regex_match(mRemaining, match, sKeyValuePattern)) {
            if (mConfigs.emplace(match[1], trimTrailingSpaces(match[2])).second) {
                return OK;
            }
            mError << "Duplicated key in configs: " << match[1] << "\n";
            return UNKNOWN_ERROR;
        }
    } else {
        // No spaces. Strictly like "CONFIG_FOO=bar"
        size_t equalPos = mRemaining.find('=');
        if (equalPos != std::string::npos) {
            std::string key = mRemaining.substr(0, equalPos);
            std::string value = mRemaining.substr(equalPos + 1);
            if (mConfigs.emplace(std::move(key), std::move(value)).second) {
                return OK;
            }
            mError << "Duplicated key in configs: " << mRemaining.substr(0, equalPos) << "\n";
            return UNKNOWN_ERROR;
        }
    }

    if (mProcessComments && std::regex_match(mRemaining, match, sNotSetPattern)) {
        if (mConfigs.emplace(match[1], "n").second) {
            return OK;
        }
        mError << "Key " << match[1] << " is set but commented as not set"
               << "\n";
        return UNKNOWN_ERROR;
    }

    if (mRelaxedFormat) {
        // Allow free format like "   #comments here"
        if (std::regex_match(mRemaining, match, sCommentPattern)) {
            return OK;
        }
    } else {
        // No leading spaces before the comment
        if (mRemaining.at(0) == '#') {
            return OK;
        }
    }

    mError << "Unrecognized line in configs: " << mRemaining << "\n";
    return UNKNOWN_ERROR;
}

status_t KernelConfigParser::process(const char* buf, size_t len) {
    const char* begin = buf;
    const char* end = buf;
    const char* stop = buf + len;
    status_t err = OK;
    while (end < stop) {
        if (*end == '\n') {
            mRemaining.insert(mRemaining.size(), begin, end - begin);
            status_t newErr = processRemaining();
            if (newErr != OK && err == OK) {
                err = newErr;
                // but continue to get more
            }
            mRemaining.clear();
            begin = end + 1;
        }
        end++;
    }
    mRemaining.insert(mRemaining.size(), begin, end - begin);
    return err;
}

}  // namespace vintf
}  // namespace android
