/*
 * 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 "ResourceValues.h"
#include "ValueVisitor.h"
#include "compile/PseudolocaleGenerator.h"
#include "compile/Pseudolocalizer.h"

#include <algorithm>

namespace aapt {

std::unique_ptr<StyledString> pseudolocalizeStyledString(StyledString* string,
                                                         Pseudolocalizer::Method method,
                                                         StringPool* pool) {
    Pseudolocalizer localizer(method);

    const StringPiece16 originalText = *string->value->str;

    StyleString localized;

    // Copy the spans. We will update their offsets when we localize.
    localized.spans.reserve(string->value->spans.size());
    for (const StringPool::Span& span : string->value->spans) {
        localized.spans.push_back(Span{ *span.name, span.firstChar, span.lastChar });
    }

    // The ranges are all represented with a single value. This is the start of one range and
    // end of another.
    struct Range {
        size_t start;

        // Once the new string is localized, these are the pointers to the spans to adjust.
        // Since this struct represents the start of one range and end of another, we have
        // the two pointers respectively.
        uint32_t* updateStart;
        uint32_t* updateEnd;
    };

    auto cmp = [](const Range& r, size_t index) -> bool {
        return r.start < index;
    };

    // Construct the ranges. The ranges are represented like so: [0, 2, 5, 7]
    // The ranges are the spaces in between. In this example, with a total string length of 9,
    // the vector represents: (0,1], (2,4], (5,6], (7,9]
    //
    std::vector<Range> ranges;
    ranges.push_back(Range{ 0 });
    ranges.push_back(Range{ originalText.size() - 1 });
    for (size_t i = 0; i < string->value->spans.size(); i++) {
        const StringPool::Span& span = string->value->spans[i];

        // Insert or update the Range marker for the start of this span.
        auto iter = std::lower_bound(ranges.begin(), ranges.end(), span.firstChar, cmp);
        if (iter != ranges.end() && iter->start == span.firstChar) {
            iter->updateStart = &localized.spans[i].firstChar;
        } else {
            ranges.insert(iter,
                          Range{ span.firstChar, &localized.spans[i].firstChar, nullptr });
        }

        // Insert or update the Range marker for the end of this span.
        iter = std::lower_bound(ranges.begin(), ranges.end(), span.lastChar, cmp);
        if (iter != ranges.end() && iter->start == span.lastChar) {
            iter->updateEnd = &localized.spans[i].lastChar;
        } else {
            ranges.insert(iter,
                          Range{ span.lastChar, nullptr, &localized.spans[i].lastChar });
        }
    }

    localized.str += localizer.start();

    // Iterate over the ranges and localize each section.
    for (size_t i = 0; i < ranges.size(); i++) {
        const size_t start = ranges[i].start;
        size_t len = originalText.size() - start;
        if (i + 1 < ranges.size()) {
            len = ranges[i + 1].start - start;
        }

        if (ranges[i].updateStart) {
            *ranges[i].updateStart = localized.str.size();
        }

        if (ranges[i].updateEnd) {
            *ranges[i].updateEnd = localized.str.size();
        }

        localized.str += localizer.text(originalText.substr(start, len));
    }

    localized.str += localizer.end();

    std::unique_ptr<StyledString> localizedString = util::make_unique<StyledString>(
            pool->makeRef(localized));
    localizedString->setSource(string->getSource());
    return localizedString;
}

namespace {

struct Visitor : public RawValueVisitor {
    StringPool* mPool;
    Pseudolocalizer::Method mMethod;
    Pseudolocalizer mLocalizer;

    // Either value or item will be populated upon visiting the value.
    std::unique_ptr<Value> mValue;
    std::unique_ptr<Item> mItem;

    Visitor(StringPool* pool, Pseudolocalizer::Method method) :
            mPool(pool), mMethod(method), mLocalizer(method) {
    }

    void visit(Array* array) override {
        std::unique_ptr<Array> localized = util::make_unique<Array>();
        localized->items.resize(array->items.size());
        for (size_t i = 0; i < array->items.size(); i++) {
            Visitor subVisitor(mPool, mMethod);
            array->items[i]->accept(&subVisitor);
            if (subVisitor.mItem) {
                localized->items[i] = std::move(subVisitor.mItem);
            } else {
                localized->items[i] = std::unique_ptr<Item>(array->items[i]->clone(mPool));
            }
        }
        localized->setSource(array->getSource());
        localized->setWeak(true);
        mValue = std::move(localized);
    }

    void visit(Plural* plural) override {
        std::unique_ptr<Plural> localized = util::make_unique<Plural>();
        for (size_t i = 0; i < plural->values.size(); i++) {
            Visitor subVisitor(mPool, mMethod);
            if (plural->values[i]) {
                plural->values[i]->accept(&subVisitor);
                if (subVisitor.mValue) {
                    localized->values[i] = std::move(subVisitor.mItem);
                } else {
                    localized->values[i] = std::unique_ptr<Item>(plural->values[i]->clone(mPool));
                }
            }
        }
        localized->setSource(plural->getSource());
        localized->setWeak(true);
        mValue = std::move(localized);
    }

    void visit(String* string) override {
        if (!string->isTranslateable()) {
            return;
        }

        std::u16string result = mLocalizer.start() + mLocalizer.text(*string->value) +
                mLocalizer.end();
        std::unique_ptr<String> localized = util::make_unique<String>(mPool->makeRef(result));
        localized->setSource(string->getSource());
        localized->setWeak(true);
        mItem = std::move(localized);
    }

    void visit(StyledString* string) override {
        if (!string->isTranslateable()) {
            return;
        }

        mItem = pseudolocalizeStyledString(string, mMethod, mPool);
        mItem->setWeak(true);
    }
};

ConfigDescription modifyConfigForPseudoLocale(const ConfigDescription& base,
                                              Pseudolocalizer::Method m) {
    ConfigDescription modified = base;
    switch (m) {
    case Pseudolocalizer::Method::kAccent:
        modified.language[0] = 'e';
        modified.language[1] = 'n';
        modified.country[0] = 'X';
        modified.country[1] = 'A';
        break;

    case Pseudolocalizer::Method::kBidi:
        modified.language[0] = 'a';
        modified.language[1] = 'r';
        modified.country[0] = 'X';
        modified.country[1] = 'B';
        break;
    default:
        break;
    }
    return modified;
}

void pseudolocalizeIfNeeded(const Pseudolocalizer::Method method,
                            ResourceConfigValue* originalValue,
                            StringPool* pool,
                            ResourceEntry* entry) {
    Visitor visitor(pool, method);
    originalValue->value->accept(&visitor);

    std::unique_ptr<Value> localizedValue;
    if (visitor.mValue) {
        localizedValue = std::move(visitor.mValue);
    } else if (visitor.mItem) {
        localizedValue = std::move(visitor.mItem);
    }

    if (!localizedValue) {
        return;
    }

    ConfigDescription configWithAccent = modifyConfigForPseudoLocale(
            originalValue->config, method);

    ResourceConfigValue* newConfigValue = entry->findOrCreateValue(
            configWithAccent, originalValue->product);
    if (!newConfigValue->value) {
        // Only use auto-generated pseudo-localization if none is defined.
        newConfigValue->value = std::move(localizedValue);
    }
}

} // namespace

bool PseudolocaleGenerator::consume(IAaptContext* context, ResourceTable* table) {
    for (auto& package : table->packages) {
        for (auto& type : package->types) {
            for (auto& entry : type->entries) {
                std::vector<ResourceConfigValue*> values = entry->findAllValues(
                        ConfigDescription::defaultConfig());
                for (ResourceConfigValue* value : values) {
                    pseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value,
                                           &table->stringPool, entry.get());
                    pseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value,
                                           &table->stringPool, entry.get());
                }
            }
        }
    }
    return true;
}

} // namespace aapt
