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

#ifndef AST_H_

#define AST_H_

#include <android-base/macros.h>
#include <map>
#include <set>
#include <string>
#include <vector>

#include "FQName.h"
#include "Type.h"

namespace android {

struct Coordinator;
struct Formatter;
struct Interface;
struct Method;
struct NamedType;
struct TypedVar;
struct Scope;

struct AST {
    AST(Coordinator *coordinator, const std::string &path);
    ~AST();

    bool setPackage(const char *package);
    bool addImport(const char *import);

    // package and version really.
    FQName package() const;
    bool isInterface(std::string *ifaceName) const;

    void enterScope(Scope *container);
    void leaveScope();
    Scope *scope();

    // Returns true iff successful.
    bool addTypeDef(const char *localName, Type *type, std::string *errorMsg);

    // Returns true iff successful.
    bool addScopedType(NamedType *type, std::string *errorMsg);

    void *scanner();
    void setScanner(void *scanner);

    const std::string &getFilename() const;

    // Look up a type by FQName, "pure" names, i.e. those without package
    // or version are first looked up in the current scope chain.
    // After that lookup proceeds to imports.
    Type *lookupType(const char *name);

    void addImportedAST(AST *ast);

    status_t generateCpp(const std::string &outputPath) const;
    status_t generateCppImpl(const std::string &outputPath) const;

    status_t generateJava(
            const std::string &outputPath,
            const std::string &limitToType) const;

    status_t generateJavaTypes(
            const std::string &outputPath,
            const std::string &limitToType) const;

    void getImportedPackages(std::set<FQName> *importSet) const;

    status_t generateVts(const std::string &outputPath) const;

    bool isJavaCompatible() const;

    // Return the set of FQNames for those interfaces and types that are
    // actually referenced in the AST, not merely imported.

    const std::set<FQName>& getImportedNames() const {
        return mImportedNames;
    }

private:
    Coordinator *mCoordinator;
    std::string mPath;
    std::vector<Scope *> mScopePath;

    void *mScanner;
    Scope *mRootScope;

    FQName mPackage;

    // A set of all external interfaces/types that are _actually_ referenced
    // in this AST, this is a subset of those specified in import statements.
    std::set<FQName> mImportedNames;

    // Similar to mImportedNames, but all types references from "types.hal"
    // are individually listed.
    std::set<FQName> mImportedNamesForJava;

    // A set of all ASTs we explicitly or implicitly (types.hal) import.
    std::set<AST *> mImportedASTs;

    // Types keyed by full names defined in this AST.
    std::map<FQName, Type *> mDefinedTypesByFullName;

    bool addScopedTypeInternal(
            NamedType *type,
            std::string *errorMsg);

    // Find a type matching fqName (which may be partial) and if found
    // return the associated type and fill in the full "matchingName".
    // Only types defined in this very AST are considered.
    Type *findDefinedType(const FQName &fqName, FQName *matchingName) const;

    void getPackageComponents(std::vector<std::string> *components) const;

    void getPackageAndVersionComponents(
            std::vector<std::string> *components, bool cpp_compatible) const;

    std::string makeHeaderGuard(const std::string &baseName) const;
    void enterLeaveNamespace(Formatter &out, bool enter) const;

    status_t generateInterfaceHeader(const std::string &outputPath) const;
    status_t generateHwBinderHeader(const std::string &outputPath) const;
    status_t generateStubHeader(const std::string &outputPath) const;
    status_t generateProxyHeader(const std::string &outputPath) const;
    status_t generateAllSource(const std::string &outputPath) const;
    status_t generatePassthroughHeader(const std::string &outputPath) const;

    status_t generateTypeSource(
            Formatter &out, const std::string &ifaceName) const;

    enum MethodLocation {
        PROXY_HEADER,
        STUB_HEADER,
        IMPL_HEADER,
        IMPL_SOURCE,
        PASSTHROUGH_HEADER
    };

    status_t generateStubImplHeader(const std::string &outputPath) const;
    status_t generateStubImplSource(const std::string &outputPath) const;

    status_t generateMethods(Formatter &out,
                             const std::string &className,
                             MethodLocation type,
                             bool specifyNamespaces) const;
    status_t generateStubMethod(Formatter &out,
                                const std::string &className,
                                const Method *method,
                                bool specifyNamespaces) const;
    status_t generateProxyDeclaration(Formatter &out,
                                      const std::string &className,
                                      const Method *method,
                                      bool specifyNamespaces) const;
    status_t generateStubImplDeclaration(Formatter &out,
                                         const std::string &className,
                                         const Method *method,
                                         bool specifyNamespaces) const;
    status_t generateStubImplMethod(Formatter &out,
                                    const std::string &className,
                                    const Method *method,
                                    bool specifyNamespaces) const;
    status_t generatePassthroughMethod(Formatter &out,
                                       const std::string &className,
                                       const Method *method,
                                       bool specifyNamespaces) const;

    void generateFetchSymbol(Formatter &out, const std::string &ifaceName) const;

    status_t generateProxySource(
            Formatter &out, const std::string &baseName) const;

    status_t generateStubSource(
            Formatter &out, const std::string &baseName) const;

    status_t generateStubSourceForMethod(
            Formatter &out, const Interface *iface, const Method *method) const;

    status_t generatePassthroughSource(Formatter &out) const;

    void declareCppReaderLocals(
            Formatter &out, const std::vector<TypedVar *> &arg) const;

    void emitCppReaderWriter(
            Formatter &out,
            const std::string &parcelObj,
            bool parcelObjIsPointer,
            const TypedVar *arg,
            bool isReader,
            Type::ErrorMode mode) const;

    void emitJavaReaderWriter(
            Formatter &out,
            const std::string &parcelObj,
            const TypedVar *arg,
            bool isReader) const;

    status_t emitTypeDeclarations(Formatter &out) const;
    status_t emitJavaTypeDeclarations(Formatter &out) const;
    status_t emitVtsTypeDeclarations(Formatter &out) const;

    // Helper function that generates vts type declaration from the current
    // AST and the transitive closure of imported ASTs.
    status_t emitVtsTypeDeclarationsHelper(
                Formatter &out,
                std::set<AST*> *allImportSet) const;

    DISALLOW_COPY_AND_ASSIGN(AST);
};

}  // namespace android

#endif  // AST_H_
