/*
 * 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 <hidl-hash/Hash.h>
#include <hidl-util/FQName.h>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <vector>

#include "Scope.h"
#include "Type.h"

namespace android {

struct Coordinator;
struct ConstantExpression;
struct DocComment;
struct EnumValue;
struct Formatter;
struct Interface;
struct Location;
struct Method;
struct NamedType;
template <class T>
struct NamedReference;
struct Type;

struct ImportStatement {
    FQName fqName;
    Location location;
};

struct AST {
    AST(const Coordinator* coordinator, const Hash* fileHash);

    bool setPackage(const char *package);
    bool addImport(const char* import, const Location& location);
    bool addImplicitImport(const FQName& fqName);

    // package and version really.
    FQName package() const;
    bool isInterface() const;
    bool definesInterfaces() const;

    // Adds package, version and scope stack to local name
    FQName makeFullName(const char* localName, Scope* scope) const;

    void addScopedType(NamedType* type, Scope* scope);

    const std::string& getFilename() const;
    const Hash* getFileHash() const;

    const Coordinator& getCoordinator() const;

    // Look up local identifier.
    // It could be plain identifier or enum value as described by lookupEnumValue.
    LocalIdentifier* lookupLocalIdentifier(const Reference<LocalIdentifier>& ref,
                                           const Scope* scope);

    // Look up an enum value by "FQName:valueName".
    EnumValue* lookupEnumValue(const FQName& fqName, std::string* errorMsg, const Scope* scope);

    // 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 FQName& fqName, const Scope* scope);

    void addImportedAST(AST *ast);

    // Calls all passes after parsing required before
    // being ready to generate output.
    status_t postParse();

    // Recursive pass on constant expression tree
    status_t constantExpressionRecursivePass(
        const std::function<status_t(ConstantExpression*)>& func, bool processBeforeDependencies);
    status_t constantExpressionRecursivePass(
        const std::function<status_t(const ConstantExpression*)>& func,
        bool processBeforeDependencies) const;

    // Recursive tree pass that sets ParseStage of all types to newStage.
    status_t setParseStage(Type::ParseStage oldStage, Type::ParseStage newStage);

    // Recursive tree pass that looks up all referenced types
    status_t lookupTypes();

    // Recursive tree pass that looks up all referenced local identifiers
    // and types referenced by constant expressions
    status_t lookupConstantExpressions();

    // Recursive tree pass that validates that all defined types
    // have unique names in their scopes.
    status_t validateDefinedTypesUniqueNames() const;

    // Recursive tree pass that completes type declarations
    // that depend on super types
    status_t resolveInheritance();

    // Recursive tree pass that validates constant expressions
    status_t validateConstantExpressions() const;

    // Recursive tree pass that evaluates constant expressions
    status_t evaluateConstantExpressions();

    // Recursive tree pass that validates all type-related
    // syntax restrictions
    status_t validate() const;

    // Recursive tree pass that ensures that type definitions and references
    // are acyclic and reorderes type definitions in reversed topological order.
    status_t topologicalReorder();

    // Recursive tree pass that ensures that constant expressions
    // are acyclic.
    status_t checkAcyclicConstantExpressions() const;

    // Recursive tree pass that checks C++ forward declaration restrictions.
    status_t checkForwardReferenceRestrictions() const;

    status_t gatherReferencedTypes();

    void generateCppSource(Formatter& out) const;

    void generateInterfaceHeader(Formatter& out) const;
    void generateHwBinderHeader(Formatter& out) const;
    void generateStubHeader(Formatter& out) const;
    void generateProxyHeader(Formatter& out) const;
    void generatePassthroughHeader(Formatter& out) const;

    void generateCppImplHeader(Formatter& out) const;
    void generateCppImplSource(Formatter& out) const;

    void generateCppAdapterHeader(Formatter& out) const;
    void generateCppAdapterSource(Formatter& out) const;

    void generateJava(Formatter& out, const std::string& limitToType) const;
    void generateJavaImpl(Formatter& out) const;
    void generateJavaTypes(Formatter& out, const std::string& limitToType) const;

    void generateVts(Formatter& out) const;

    void generateDependencies(Formatter& out) const;
    void generateInheritanceHierarchy(Formatter& out) const;

    void generateFormattedHidl(Formatter& out) const;

    const std::vector<ImportStatement>& getImportStatements() const;
    void getImportedPackages(std::set<FQName> *importSet) const;

    // Run getImportedPackages on this, then run getImportedPackages on
    // each AST in each package referenced in importSet.
    void getImportedPackagesHierarchy(std::set<FQName> *importSet) const;

    bool isJavaCompatible() const;

    // Warning: this only includes names explicitly referenced in code.
    //   It does not include all names which are imported.
    //
    // Currently, there is one valid usecase for this: importing exactly
    // the names which need to be imported in generated code. If you import
    // based on getAllImportedNamesGranular instead, you will import things
    // that aren't actually used in the resultant code.
    //
    // Get transitive closure of imported interface/types. This will add
    // everything exported by a package even if only a single type from
    // that package was explicitly imported!
    void getAllImportedNames(std::set<FQName> *allImportSet) const;

    // Get imported types, this includes those explicitly imported as well
    // as all types defined in imported packages.
    void getAllImportedNamesGranular(std::set<FQName> *allImportSet) const;

    void appendToExportedTypesVector(
            std::vector<const Type *> *exportedTypes) const;

    // used by the parser.
    void addSyntaxError();
    size_t syntaxErrors() const;

    bool isIBase() const;

    // or nullptr if not isInterface
    const Interface *getInterface() const;

    // types or Interface base name (e.x. Foo)
    std::string getBaseName() const;

    Scope* getMutableRootScope();
    const Scope& getRootScope() const;

    static void generateCppPackageInclude(Formatter& out, const FQName& package,
                                          const std::string& klass);

    void addDefinedTypes(std::set<FQName> *definedTypes) const;
    void addReferencedTypes(std::set<FQName> *referencedTypes) const;

    void addToImportedNamesGranular(const FQName &fqName);

    bool addMethod(Method* method, Interface* iface);
    bool addAllReservedMethodsToInterface(Interface* iface);

    void setHeader(const DocComment* header);
    const DocComment* getHeader() const;

    // TODO: Clean up all interface usages of unhandled comments and ensure they are attached to the
    // right element
    void addUnhandledComment(const DocComment* docComment);
    const std::vector<const DocComment*> getUnhandledComments() const;

  private:
    const Coordinator* mCoordinator;
    const Hash* mFileHash;

    RootScope mRootScope;

    FQName mPackage;

    // Header for the file
    const DocComment* mHeader = nullptr;

    // A list of trailing DocComments.
    std::vector<const DocComment*> mUnhandledComments;

    // A list of the FQNames present in the import statements
    std::vector<ImportStatement> mImportStatements;

    // A list of FQNames that are imported implicitly
    std::vector<FQName> mImplicitImports;

    // A set of all external interfaces/types that are _actually_ referenced
    // in this AST, this is a subset of those specified in import statements.
    // Note that this set only resolves to the granularity of either an
    // interface type or a whole package.
    std::set<FQName> mImportedNames;

    // This is the set of actually imported types.
    std::set<FQName> mImportedNamesGranular;

    // Warning: this only includes names explicitly referenced in code.
    //   It does not include all names which are imported.
    //
    // A set of all ASTs we explicitly or implicitly (types.hal) import.
    std::set<AST *> mImportedASTs;

    // If a single type (instead of the whole AST) is imported, the AST will be
    // present as a key to this map, with the value being a list of types
    // imported from this AST. If an AST appears in mImportedASTs but not in
    // mImportedTypes, then the whole AST is imported.
    std::map<AST *, std::set<Type *>> mImportedTypes;

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

    // contains all the hidl reserved methods part of this AST
    std::map<std::string, Method*> mAllReservedMethods;

    // used by the parser.
    size_t mSyntaxErrors = 0;

    std::set<FQName> mReferencedTypeNames;

    // importFQName will try to import fqName by parsing any file that might contain it
    bool importFQName(const FQName& fqName);

    // Helper functions for lookupType.
    Type* lookupTypeLocally(const FQName& fqName, const Scope* scope);
    status_t lookupAutofilledType(const FQName &fqName, Type **returnedType);
    Type *lookupTypeFromImports(const FQName &fqName);

    // 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;

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

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

    // a method, and in which interface is it originally defined.
    // be careful of the case where method.isHidlReserved(), where interface
    // is effectively useless.
    using MethodGenerator = std::function<void(const Method*, const Interface*)>;

    void generateTemplatizationLink(Formatter& out) const;
    void generateCppTag(Formatter& out, const std::string& tag) const;

    void generateMethods(Formatter& out, const MethodGenerator& gen,
                         bool includeParents = true) const;
    void generateStubImplMethod(Formatter& out, const std::string& className,
                                const Method* method) const;
    void generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const;
    void generateStaticProxyMethodSource(Formatter& out, const std::string& className,
                                         const Method* method, const Interface* superInterface) const;
    void generateProxyMethodSource(Formatter& out, const std::string& className,
                                   const Method* method, const Interface* superInterface) const;
    void generateAdapterMethod(Formatter& out, const Method* method) const;

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

    void generateProxySource(Formatter& out, const FQName& fqName) const;

    void generateStubSource(Formatter& out, const Interface* iface) const;

    void generateStubSourceForMethod(Formatter& out, const Method* method,
                                     const Interface* superInterface) const;
    void generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
                                        const Method* method, const Interface* superInterface) const;

    void generatePassthroughSource(Formatter& out) const;

    void generateInterfaceSource(Formatter& out) const;

    enum InstrumentationEvent {
        SERVER_API_ENTRY = 0,
        SERVER_API_EXIT,
        CLIENT_API_ENTRY,
        CLIENT_API_EXIT,
        SYNC_CALLBACK_ENTRY,
        SYNC_CALLBACK_EXIT,
        ASYNC_CALLBACK_ENTRY,
        ASYNC_CALLBACK_EXIT,
        PASSTHROUGH_ENTRY,
        PASSTHROUGH_EXIT,
    };

    void generateCppAtraceCall(
            Formatter &out,
            InstrumentationEvent event,
            const Method *method) const;

    void generateCppInstrumentationCall(
            Formatter &out,
            InstrumentationEvent event,
            const Method *method,
            const Interface* superInterface) const;

    void declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& arg,
                                bool forResults) const;

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

    void emitJavaReaderWriter(Formatter& out, const std::string& parcelObj,
                              const NamedReference<Type>* arg, bool isReader,
                              bool addPrefixToName) const;

    void emitVtsTypeDeclarations(Formatter& out) const;

    DISALLOW_COPY_AND_ASSIGN(AST);
};

}  // namespace android

#endif  // AST_H_
