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

#include "Annotation.h"
#include "Coordinator.h"
#include "Interface.h"
#include "Method.h"
#include "Scope.h"

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

namespace android {

status_t AST::emitVtsTypeDeclarations(Formatter &out) const {
    std::set<AST *> allImportedASTs;
    return emitVtsTypeDeclarationsHelper(out, &allImportedASTs);
}

status_t AST::emitVtsTypeDeclarationsHelper(
        Formatter &out,
        std::set<AST *> *allImportSet) const {
    // First, generate vts type declaration for all imported AST.
    for (const auto &ast : mImportedASTs) {
        // Already processed, skip.
        if (allImportSet->find(ast) != allImportSet->end()) {
            continue;
        }
        allImportSet->insert(ast);
        std::string ifaceName;
        // Skip the process of ast within the same package.
        if (ast->package() != mPackage) {
            status_t status = ast->emitVtsTypeDeclarationsHelper(out,
                                                                 allImportSet);
            if (status != OK) {
                return status;
            }
        }
    }
    // Next, generate vts type declaration for the current AST.
    std::string ifaceName;
    // We only care about types.hal.
    if (!AST::isInterface(&ifaceName)) {
        for (const auto &type : mRootScope->getSubTypes()) {
            // Skip for TypeDef as it is just an alias of a defined type.
            if (type->isTypeDef()) {
                continue;
            }
            out << "attribute: {\n";
            out.indent();
            status_t status = type->emitVtsTypeDeclarations(out);
            if (status != OK) {
                return status;
            }
            out.unindent();
            out << "}\n\n";
        }
    }
    return OK;
}

status_t AST::generateVts(const std::string &outputPath) const {
    std::string path = outputPath;
    path.append(mCoordinator->convertPackageRootToPath(mPackage));
    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));

    std::string ifaceName;
    std::string baseName;

    bool isInterface = true;
    if (!AST::isInterface(&ifaceName)) {
        baseName = "types";
        isInterface = false;
    } else {
        const Interface *iface = mRootScope->getInterface();
        baseName = iface->getBaseName();
    }

    path.append(baseName);
    path.append(".vts");

    CHECK(Coordinator::MakeParentHierarchy(path));
    FILE *file = fopen(path.c_str(), "w");

    if (file == NULL) {
        return -errno;
    }

    Formatter out(file);

    out << "component_class: HAL_HIDL\n";
    out << "component_type_version: " << mPackage.version()
        << "\n";
    out << "component_name: \""
        << (isInterface ? ifaceName : "types")
        << "\"\n\n";

    out << "package: \"" << mPackage.package() << "\"\n\n";

    for (const auto &item : mImportedNames) {
        // ignore IBase.
        if (item != gIBaseFqName) {
            out << "import: \"" << item.string() << "\"\n";
        }
    }

    out << "\n";

    if (isInterface) {
        const Interface *iface = mRootScope->getInterface();
        out << "interface: {\n";
        out.indent();

        std::vector<const Interface *> chain = iface->typeChain();

        // Generate all the attribute declarations first.
        status_t status = emitVtsTypeDeclarations(out);
        if (status != OK) {
            return status;
        }
        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
            const Interface *superInterface = *it;
            status_t status = superInterface->emitVtsAttributeDeclaration(out);
            if (status != OK) {
                return status;
            }
        }

        // Generate all the method declarations.
        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
            const Interface *superInterface = *it;
            status_t status = superInterface->emitVtsMethodDeclaration(out);
            if (status != OK) {
                return status;
            }
        }

        out.unindent();
        out << "}\n";
    } else {
        status_t status = emitVtsTypeDeclarations(out);
        if (status != OK) {
            return status;
        }
    }
    return OK;
}

}  // namespace android




