/*
 * 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.
 */

#include "ResourceTable.h"
#include "link/Linkers.h"

#include <algorithm>
#include <vector>

namespace aapt {

template <typename Iterator, typename Pred>
class FilterIterator {
public:
    FilterIterator(Iterator begin, Iterator end, Pred pred=Pred()) :
            mCurrent(begin), mEnd(end), mPred(pred) {
        advance();
    }

    bool hasNext() {
        return mCurrent != mEnd;
    }

    Iterator nextIter() {
        Iterator iter = mCurrent;
        ++mCurrent;
        advance();
        return iter;
    }

    typename Iterator::reference next() {
        return *nextIter();
    }

private:
    void advance() {
        for (; mCurrent != mEnd; ++mCurrent) {
            if (mPred(*mCurrent)) {
                return;
            }
        }
    }

    Iterator mCurrent, mEnd;
    Pred mPred;
};

template <typename Iterator, typename Pred>
FilterIterator<Iterator, Pred> makeFilterIterator(Iterator begin, Iterator end=Iterator(),
                                                  Pred pred=Pred()) {
    return FilterIterator<Iterator, Pred>(begin, end, pred);
}

/**
 * Every Configuration with an SDK version specified that is less than minSdk will be removed.
 * The exception is when there is no exact matching resource for the minSdk. The next smallest
 * one will be kept.
 */
static void collapseVersions(int minSdk, ResourceEntry* entry) {
    // First look for all sdks less than minSdk.
    for (auto iter = entry->values.rbegin(); iter != entry->values.rend(); ++iter) {
        // Check if the item was already marked for removal.
        if (!(*iter)) {
            continue;
        }

        const ConfigDescription& config = (*iter)->config;
        if (config.sdkVersion <= minSdk) {
            // This is the first configuration we've found with a smaller or equal SDK level
            // to the minimum. We MUST keep this one, but remove all others we find, which get
            // overridden by this one.

            ConfigDescription configWithoutSdk = config;
            configWithoutSdk.sdkVersion = 0;
            auto pred = [&](const std::unique_ptr<ResourceConfigValue>& val) -> bool {
                // Check that the value hasn't already been marked for removal.
                if (!val) {
                    return false;
                }

                // Only return Configs that differ in SDK version.
                configWithoutSdk.sdkVersion = val->config.sdkVersion;
                return configWithoutSdk == val->config && val->config.sdkVersion <= minSdk;
            };

            // Remove the rest that match.
            auto filterIter = makeFilterIterator(iter + 1, entry->values.rend(), pred);
            while (filterIter.hasNext()) {
                filterIter.next() = {};
            }
        }
    }

    // Now erase the nullptr values.
    entry->values.erase(std::remove_if(entry->values.begin(), entry->values.end(),
                   [](const std::unique_ptr<ResourceConfigValue>& val) -> bool {
        return val == nullptr;
    }), entry->values.end());
}

bool VersionCollapser::consume(IAaptContext* context, ResourceTable* table) {
    const int minSdk = context->getMinSdkVersion();
    for (auto& package : table->packages) {
        for (auto& type : package->types) {
            for (auto& entry : type->entries) {
                collapseVersions(minSdk, entry.get());
            }
        }
    }
    return true;
}

} // namespace aapt
