/*
 * Copyright 2017, 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 MODULE_H
#define MODULE_H

#include <iostream>
#include <map>
#include <vector>

#include "core_defs.h"
#include "entity.h"
#include "instructions.h"
#include "stl_util.h"
#include "types_generated.h"
#include "visitor.h"

namespace android {
namespace spirit {

class Builder;
class AnnotationSection;
class CapabilityInst;
class DebugInfoSection;
class ExtensionInst;
class ExtInstImportInst;
class EntryPointInst;
class ExecutionModeInst;
class EntryPointDefinition;
class FunctionDeclaration;
class FunctionDefinition;
class GlobalSection;
class InputWordStream;
class Instruction;
class MemoryModelInst;

union VersionNumber {
  struct {
    uint8_t mLowZero;
    uint8_t mMinorNumber;
    uint8_t mMajorNumber;
    uint8_t mHighZero;
  } mMajorMinor;
  uint8_t mBytes[4];
  uint32_t mWord;
};

class Module : public Entity {
public:
  static Module *getCurrentModule();
  uint32_t nextId() { return mNextId++; }

  Module();

  Module(Builder *b);

  virtual ~Module() {}

  bool DeserializeInternal(InputWordStream &IS) override;

  void Serialize(OutputWordStream &OS) const override;

  void SerializeHeader(OutputWordStream &OS) const;

  void registerId(uint32_t id, Instruction *inst) {
    mIdTable.insert(std::make_pair(id, inst));
  }

  void initialize();

  bool resolveIds();

  void accept(IVisitor *v) override {
    for (auto cap : mCapabilities) {
      v->visit(cap);
    }
    for (auto ext : mExtensions) {
      v->visit(ext);
    }
    for (auto imp : mExtInstImports) {
      v->visit(imp);
    }

    v->visit(mMemoryModel.get());

    for (auto entry : mEntryPoints) {
      v->visit(entry);
    }

    for (auto mode : mExecutionModes) {
      v->visit(mode);
    }

    v->visit(mDebugInfo.get());
    if (mAnnotations) {
      v->visit(mAnnotations.get());
    }
    if (mGlobals) {
      v->visit(mGlobals.get());
    }

    for (auto def : mFunctionDefinitions) {
      v->visit(def);
    }
  }

  static std::ostream &errs() { return std::cerr; }

  Module *addCapability(Capability cap);
  Module *setMemoryModel(AddressingModel am, MemoryModel mm);
  Module *addExtInstImport(const char *extName);
  Module *addSource(SourceLanguage lang, int version);
  Module *addSourceExtension(const char *ext);
  Module *addString(const char *ext);
  Module *addEntryPoint(EntryPointDefinition *entry);

  ExtInstImportInst *getGLExt() const { return mGLExt; }

  GlobalSection *getGlobalSection();

  Instruction *lookupByName(const char *) const;
  FunctionDefinition *
  getFunctionDefinitionFromInstruction(FunctionInst *) const;
  FunctionDefinition *lookupFunctionDefinitionByName(const char *name) const;

  // Find the name of the instruction, e.g., the name of a function (OpFunction
  // instruction).
  // The returned string is owned by the OpName instruction, whose first operand
  // is the instruction being queried on.
  const char *lookupNameByInstruction(const Instruction *) const;

  VariableInst *getInvocationId();
  VariableInst *getNumWorkgroups();

  // Adds a struct type built somewhere else.
  Module *addStructType(TypeStructInst *structType);
  Module *addVariable(VariableInst *var);

  // Methods to look up types. Create them if not found.
  TypeVoidInst *getVoidType();
  TypeIntInst *getIntType(int bits, bool isSigned = true);
  TypeIntInst *getUnsignedIntType(int bits);
  TypeFloatInst *getFloatType(int bits);
  TypeVectorInst *getVectorType(Instruction *componentType, int width);
  TypePointerInst *getPointerType(StorageClass storage,
                                  Instruction *pointeeType);
  TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);

  // This implies that struct types are strictly structural equivalent, i.e.,
  // two structs are equivalent i.f.f. their fields are equivalent, recursively.
  TypeStructInst *getStructType(Instruction *fieldType[], int numField);
  TypeStructInst *getStructType(const std::vector<Instruction *> &fieldType);
  TypeStructInst *getStructType(Instruction *field0Type);
  TypeStructInst *getStructType(Instruction *field0Type,
                                Instruction *field1Type);
  TypeStructInst *getStructType(Instruction *field0Type,
                                Instruction *field1Type,
                                Instruction *field2Type);

  // TODO: Can function types of different decorations be considered the same?
  TypeFunctionInst *getFunctionType(Instruction *retType,
                                    Instruction *const argType[],
                                    size_t numArg);
  TypeFunctionInst *getFunctionType(Instruction *retType,
                                    const std::vector<Instruction *> &argTypes);

  size_t getSize(TypeVoidInst *voidTy);
  size_t getSize(TypeIntInst *intTy);
  size_t getSize(TypeFloatInst *fpTy);
  size_t getSize(TypeVectorInst *vTy);
  size_t getSize(TypePointerInst *ptrTy);
  size_t getSize(TypeStructInst *structTy);
  size_t getSize(TypeFunctionInst *funcTy);
  size_t getSize(Instruction *inst);

  ConstantInst *getConstant(TypeIntInst *type, int32_t value);
  ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
  ConstantInst *getConstant(TypeFloatInst *type, float value);

  ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
                                              ConstantInst *components[],
                                              size_t width);
  ConstantCompositeInst *
  getConstantComposite(Instruction *type,
                       const std::vector<ConstantInst *> &components);
  ConstantCompositeInst *getConstantComposite(Instruction *type,
                                              ConstantInst *comp0,
                                              ConstantInst *comp1);
  ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
                                              ConstantInst *comp0,
                                              ConstantInst *comp1,
                                              ConstantInst *comp2);
  ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
                                              ConstantInst *comp0,
                                              ConstantInst *comp1,
                                              ConstantInst *comp2,
                                              ConstantInst *comp3);

  Module *addFunctionDefinition(FunctionDefinition *func);

  void consolidateAnnotations();

private:
  static Module *mInstance;
  uint32_t mNextId;
  std::map<uint32_t, Instruction *> mIdTable;

  uint32_t mMagicNumber;
  VersionNumber mVersion;
  uint32_t mGeneratorMagicNumber;
  uint32_t mBound;
  uint32_t mReserved;

  std::vector<CapabilityInst *> mCapabilities;
  std::vector<ExtensionInst *> mExtensions;
  std::vector<ExtInstImportInst *> mExtInstImports;
  std::unique_ptr<MemoryModelInst> mMemoryModel;
  std::vector<EntryPointInst *> mEntryPointInsts;
  std::vector<ExecutionModeInst *> mExecutionModes;
  std::vector<EntryPointDefinition *> mEntryPoints;
  std::unique_ptr<DebugInfoSection> mDebugInfo;
  std::unique_ptr<AnnotationSection> mAnnotations;
  std::unique_ptr<GlobalSection> mGlobals;
  std::vector<FunctionDefinition *> mFunctionDefinitions;

  ExtInstImportInst *mGLExt;

  ContainerDeleter<std::vector<CapabilityInst *>> mCapabilitiesDeleter;
  ContainerDeleter<std::vector<ExtensionInst *>> mExtensionsDeleter;
  ContainerDeleter<std::vector<ExtInstImportInst *>> mExtInstImportsDeleter;
  ContainerDeleter<std::vector<EntryPointInst *>> mEntryPointInstsDeleter;
  ContainerDeleter<std::vector<ExecutionModeInst *>> mExecutionModesDeleter;
  ContainerDeleter<std::vector<EntryPointDefinition *>> mEntryPointsDeleter;
  ContainerDeleter<std::vector<FunctionDefinition *>>
      mFunctionDefinitionsDeleter;
};

struct Extent3D {
  uint32_t mWidth;
  uint32_t mHeight;
  uint32_t mDepth;
};

class EntryPointDefinition : public Entity {
public:
  EntryPointDefinition() {}
  EntryPointDefinition(Builder *builder, ExecutionModel execModel,
                       FunctionDefinition *func, const char *name);

  virtual ~EntryPointDefinition() {
    // Nothing to do here since ~Module() will delete entities referenced here
  }

  void accept(IVisitor *visitor) override {
    visitor->visit(mEntryPointInst);
    // Do not visit the ExecutionMode instructions here. They are linked here
    // for convinience, and for convinience only. They are all grouped, stored,
    // and serialized directly in the module in a section right after all
    // EntryPoint instructions. Visit them from there.
  }

  bool DeserializeInternal(InputWordStream &IS) override;

  EntryPointDefinition *addToInterface(VariableInst *var);
  EntryPointDefinition *addExecutionMode(ExecutionModeInst *mode) {
    mExecutionModeInsts.push_back(mode);
    return this;
  }
  const std::vector<ExecutionModeInst *> &getExecutionModes() const {
    return mExecutionModeInsts;
  }

  EntryPointDefinition *setLocalSize(uint32_t width, uint32_t height,
                                     uint32_t depth);

  EntryPointDefinition *applyExecutionMode(ExecutionModeInst *mode);

  EntryPointInst *getInstruction() const { return mEntryPointInst; }

private:
  const char *mName;
  FunctionInst *mFunction;
  ExecutionModel mExecutionModel;
  std::vector<VariableInst *> mInterface;
  Extent3D mLocalSize;

  EntryPointInst *mEntryPointInst;
  std::vector<ExecutionModeInst *> mExecutionModeInsts;
};

class DebugInfoSection : public Entity {
public:
  DebugInfoSection() : mSourcesDeleter(mSources), mNamesDeleter(mNames) {}
  DebugInfoSection(Builder *b)
      : Entity(b), mSourcesDeleter(mSources), mNamesDeleter(mNames) {}

  virtual ~DebugInfoSection() {}

  bool DeserializeInternal(InputWordStream &IS) override;

  DebugInfoSection *addSource(SourceLanguage lang, int version);
  DebugInfoSection *addSourceExtension(const char *ext);
  DebugInfoSection *addString(const char *str);

  Instruction *lookupByName(const char *name) const;
  const char *lookupNameByInstruction(const Instruction *) const;

  void accept(IVisitor *v) override {
    for (auto source : mSources) {
      v->visit(source);
    }
    for (auto name : mNames) {
      v->visit(name);
    }
  }

private:
  // (OpString|OpSource|OpSourceExtension|OpSourceContinued)*
  std::vector<Instruction *> mSources;
  // (OpName|OpMemberName)*
  std::vector<Instruction *> mNames;

  ContainerDeleter<std::vector<Instruction *>> mSourcesDeleter;
  ContainerDeleter<std::vector<Instruction *>> mNamesDeleter;
};

class AnnotationSection : public Entity {
public:
  AnnotationSection();
  AnnotationSection(Builder *b);

  virtual ~AnnotationSection() {}

  bool DeserializeInternal(InputWordStream &IS) override;

  void accept(IVisitor *v) override {
    for (auto inst : mAnnotations) {
      v->visit(inst);
    }
  }

  template <typename T> void addAnnotations(T begin, T end) {
    mAnnotations.insert<T>(std::end(mAnnotations), begin, end);
  }

  std::vector<Instruction *>::const_iterator begin() const {
    return mAnnotations.begin();
  }

  std::vector<Instruction *>::const_iterator end() const {
    return mAnnotations.end();
  }

  void clear() { mAnnotations.clear(); }

private:
  std::vector<Instruction *> mAnnotations; // OpDecorate, etc.

  ContainerDeleter<std::vector<Instruction *>> mAnnotationsDeleter;
};

// Types, constants, and globals
class GlobalSection : public Entity {
public:
  GlobalSection();
  GlobalSection(Builder *builder);

  virtual ~GlobalSection() {}

  bool DeserializeInternal(InputWordStream &IS) override;

  void accept(IVisitor *v) override {
    for (auto inst : mGlobalDefs) {
      v->visit(inst);
    }

    if (mInvocationId) {
      v->visit(mInvocationId.get());
    }

    if (mNumWorkgroups) {
      v->visit(mNumWorkgroups.get());
    }
  }

  ConstantInst *getConstant(TypeIntInst *type, int32_t value);
  ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
  ConstantInst *getConstant(TypeFloatInst *type, float value);
  ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
                                              ConstantInst *components[],
                                              size_t width);

  // Methods to look up types. Create them if not found.
  TypeVoidInst *getVoidType();
  TypeIntInst *getIntType(int bits, bool isSigned = true);
  TypeFloatInst *getFloatType(int bits);
  TypeVectorInst *getVectorType(Instruction *componentType, int width);
  TypePointerInst *getPointerType(StorageClass storage,
                                  Instruction *pointeeType);
  TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);

  // This implies that struct types are strictly structural equivalent, i.e.,
  // two structs are equivalent i.f.f. their fields are equivalent, recursively.
  TypeStructInst *getStructType(Instruction *fieldType[], int numField);
  // TypeStructInst *getStructType(const std::vector<Instruction *>
  // &fieldTypes);

  // TODO: Can function types of different decorations be considered the same?
  TypeFunctionInst *getFunctionType(Instruction *retType,
                                    Instruction *const argType[],
                                    size_t numArg);
  // TypeStructInst *addStructType(Instruction *fieldType[], int numField);
  GlobalSection *addStructType(TypeStructInst *structType);
  GlobalSection *addVariable(VariableInst *var);

  VariableInst *getInvocationId();
  VariableInst *getNumWorkgroups();

private:
  // TODO: Add structure to this.
  // Separate types, constants, variables, etc.
  std::vector<Instruction *> mGlobalDefs;
  std::unique_ptr<VariableInst> mInvocationId;
  std::unique_ptr<VariableInst> mNumWorkgroups;

  ContainerDeleter<std::vector<Instruction *>> mGlobalDefsDeleter;
};

class FunctionDeclaration : public Entity {
public:
  virtual ~FunctionDeclaration() {}

  bool DeserializeInternal(InputWordStream &IS) override;

  void accept(IVisitor *v) override {
    v->visit(mFunc);
    for (auto param : mParams) {
      v->visit(param);
    }
    v->visit(mFuncEnd);
  }

private:
  FunctionInst *mFunc;
  std::vector<FunctionParameterInst *> mParams;
  FunctionEndInst *mFuncEnd;
};

class Block : public Entity {
public:
  Block() {}
  Block(Builder *b) : Entity(b) {}

  virtual ~Block() {}

  bool DeserializeInternal(InputWordStream &IS) override;

  void accept(IVisitor *v) override {
    for (auto inst : mInsts) {
      v->visit(inst);
    }
  }

  Block *addInstruction(Instruction *inst) {
    mInsts.push_back(inst);
    return this;
  }

private:
  std::vector<Instruction *> mInsts;
};

class FunctionDefinition : public Entity {
public:
  FunctionDefinition();
  FunctionDefinition(Builder *builder, FunctionInst *func,
                     FunctionEndInst *end);

  virtual ~FunctionDefinition() {}

  bool DeserializeInternal(InputWordStream &IS) override;

  void accept(IVisitor *v) override {
    v->visit(mFunc.get());
    for (auto param : mParams) {
      v->visit(param);
    }
    for (auto block : mBlocks) {
      v->visit(block);
    }
    v->visit(mFuncEnd.get());
  }

  FunctionDefinition *addBlock(Block *b) {
    mBlocks.push_back(b);
    return this;
  }

  FunctionInst *getInstruction() const { return mFunc.get(); }
  FunctionParameterInst *getParameter(uint32_t i) const { return mParams[i]; }

  Instruction *getReturnType() const;

private:
  std::unique_ptr<FunctionInst> mFunc;
  std::vector<FunctionParameterInst *> mParams;
  std::vector<Block *> mBlocks;
  std::unique_ptr<FunctionEndInst> mFuncEnd;

  ContainerDeleter<std::vector<FunctionParameterInst *>> mParamsDeleter;
  ContainerDeleter<std::vector<Block *>> mBlocksDeleter;
};

} // namespace spirit
} // namespace android

#endif // MODULE_H
