/*
 * 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 "Scope.h"

#include "Annotation.h"
#include "ConstantExpression.h"
#include "Interface.h"

#include <android-base/logging.h>
#include <hidl-util/Formatter.h>
#include <hidl-util/StringHelper.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

namespace android {

Scope::Scope(const std::string& localName, const FQName& fullName, const Location& location,
             Scope* parent)
    : NamedType(localName, fullName, location, parent) {}
Scope::~Scope(){}

void Scope::addType(NamedType* type) {
    size_t index = mTypes.size();
    mTypes.push_back(type);
    mTypeIndexByName[type->definedName()] = index;
}

status_t Scope::validateUniqueNames() const {
    for (const auto* type : mTypes) {
        if (mTypes[mTypeIndexByName.at(type->definedName())] != type) {
            std::cerr << "ERROR: A type named '" << type->definedName()
                      << "' is already declared in the scope at " << type->location() << std::endl;
            return UNKNOWN_ERROR;
        }
    }
    return OK;
}

NamedType *Scope::lookupType(const FQName &fqName) const {
    CHECK(fqName.package().empty() && fqName.version().empty());
    if (!fqName.valueName().empty()) {
        std::cerr << "ERROR: " << fqName.string() << " does not refer to a type." << std::endl;
        return nullptr;
    }
    std::vector<std::string> names = fqName.names();
    CHECK_GT(names.size(), 0u);
    auto it = mTypeIndexByName.find(names[0]);

    if (it == mTypeIndexByName.end()) {
        return nullptr;
    }

    NamedType *outerType = mTypes[it->second];
    if (names.size() == 1) {
        return outerType;
    }
    if (!outerType->isScope()) {
        // more than one names, but the first name is not a scope
        return nullptr;
    }
    Scope *outerScope = static_cast<Scope *>(outerType);
    // *slowly* pop first element
    names.erase(names.begin());
    FQName innerName;
    CHECK(FQName::parse(StringHelper::JoinStrings(names, "."), &innerName));
    return outerScope->lookupType(innerName);
}

LocalIdentifier *Scope::lookupIdentifier(const std::string & /*name*/) const {
    return nullptr;
}

bool Scope::isScope() const {
    return true;
}

Interface *Scope::getInterface() const {
    if (mTypes.size() == 1 && mTypes[0]->isInterface()) {
        return static_cast<Interface *>(mTypes[0]);
    }

    return nullptr;
}

bool Scope::definesInterfaces() const {
    for (const NamedType *type : mTypes) {
        if (type->isInterface()) {
            return true;
        }
    }

    return false;
}

const std::vector<Annotation*>& Scope::annotations() const {
    return mAnnotations;
}

void Scope::setAnnotations(std::vector<Annotation*>* annotations) {
    CHECK(mAnnotations.empty());
    CHECK(annotations != nullptr);
    mAnnotations = *annotations;
}

std::vector<const Type*> Scope::getDefinedTypes() const {
    std::vector<const Type*> ret;
    ret.insert(ret.end(), mTypes.begin(), mTypes.end());
    return ret;
}

std::vector<const NamedType*> Scope::getSortedDefinedTypes() const {
    std::vector<const NamedType*> ret;
    ret.insert(ret.end(), mTypes.begin(), mTypes.end());

    std::sort(ret.begin(), ret.end(), [](const NamedType* lhs, const NamedType* rhs) -> bool {
        return lhs->location() < rhs->location();
    });
    return ret;
}

void Scope::topologicalReorder(const std::unordered_map<const Type*, size_t>& reversedOrder) {
    auto less = [&](const Type* lhs, const Type* rhs) {
        return reversedOrder.at(lhs) < reversedOrder.at(rhs);
    };

    if (std::is_sorted(mTypes.begin(), mTypes.end(), less)) return;

    mTypeOrderChanged = true;
    std::sort(mTypes.begin(), mTypes.end(), less);

    for (size_t i = 0; i != mTypes.size(); ++i) {
        mTypeIndexByName.at(mTypes[i]->definedName()) = i;
    }
}

void Scope::emitHidlDefinition(Formatter& out) const {
    const std::vector<const NamedType*>& definedTypes = getSortedDefinedTypes();
    out.join(definedTypes.begin(), definedTypes.end(), "\n",
             [&](auto t) { t->emitHidlDefinition(out); });
}

void Scope::emitTypeDeclarations(Formatter& out) const {
    if (mTypes.empty()) return;

    out << "// Forward declaration for forward reference support:\n";
    for (const Type* type : mTypes) {
        type->emitTypeForwardDeclaration(out);
    }
    out << "\n";

    if (mTypeOrderChanged) {
        out << "// Order of inner types was changed for forward reference support.\n\n";
    }

    for (const Type* type : mTypes) {
        type->emitDocComment(out);
        type->emitTypeDeclarations(out);
    }
}

void Scope::emitGlobalTypeDeclarations(Formatter& out) const {
    for (const Type* type : mTypes) {
        type->emitGlobalTypeDeclarations(out);
    }
}

void Scope::emitPackageTypeDeclarations(Formatter& out) const {
    for (const Type* type : mTypes) {
        type->emitPackageTypeDeclarations(out);
    }
}

void Scope::emitPackageTypeHeaderDefinitions(Formatter& out) const {
    for (const Type* type : mTypes) {
        type->emitPackageTypeHeaderDefinitions(out);
    }
}

void Scope::emitPackageHwDeclarations(Formatter& out) const {
    for (const Type* type : mTypes) {
        type->emitPackageHwDeclarations(out);
    }
}

void Scope::emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const {
    if (mTypeOrderChanged) {
        out << "// Order of inner types was changed for forward reference support.\n\n";
    }

    for (const Type* type : mTypes) {
        type->emitDocComment(out);
        type->emitJavaTypeDeclarations(out, atTopLevel);
    }
}

void Scope::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
    for (const Type* type : mTypes) {
        type->emitTypeDefinitions(out, prefix);
    }
}

const std::vector<NamedType *> &Scope::getSubTypes() const {
    return mTypes;
}

void Scope::emitVtsTypeDeclarations(Formatter& out) const {
    for (const Type* type : mTypes) {
        type->emitVtsTypeDeclarations(out);
    }
}

bool Scope::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
    for (const Type* type : mTypes) {
        // Java compatibility focuses on types that are actually used by interfaces.
        // Declarations of java-incompatible types are simply omitted from
        // corresponding Java libraries.
        if (type->isInterface() && !type->isJavaCompatible(visited)) {
            return false;
        }
    }

    return Type::deepIsJavaCompatible(visited);
}

void Scope::appendToExportedTypesVector(
        std::vector<const Type *> *exportedTypes) const {
    for (const Type* type : mTypes) {
        type->appendToExportedTypesVector(exportedTypes);
    }
}

////////////////////////////////////////

RootScope::RootScope(const char* localName, const FQName& fullName, const Location& location,
                     Scope* parent)
    : Scope(localName, fullName, location, parent) {}
RootScope::~RootScope() {}

std::string RootScope::typeName() const {
    return "(root scope)";
}

status_t RootScope::validate() const {
    CHECK(annotations().empty());
    return Scope::validate();
}

////////////////////////////////////////

LocalIdentifier::LocalIdentifier(){}
LocalIdentifier::~LocalIdentifier(){}

bool LocalIdentifier::isEnumValue() const {
    return false;
}

const LocalIdentifier* LocalIdentifier::resolve() const {
    return this;
}

LocalIdentifier* LocalIdentifier::resolve() {
    return this;
}

ConstantExpression* LocalIdentifier::constExpr() const {
    return nullptr;
}

}  // namespace android

