/*
 * Copyright 2010-2011, 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 _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  // NOLINT
#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_

#include <fstream>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

#include "llvm/ADT/StringExtras.h"

#include "slang_assert.h"
#include "slang_rs_export_type.h"

namespace slang {

  class RSContext;
  class RSExportVar;
  class RSExportFunc;
  class RSExportForEach;

class RSReflection {
 private:
  const RSContext *mRSContext;

  std::string mLastError;
  std::vector<std::string> *mGeneratedFileNames;

  inline void setError(const std::string &Error) { mLastError = Error; }

  class Context {
   private:
    static const char *const ApacheLicenseNote;

    static const char *const Import[];

    bool mVerbose;

    std::string mOutputPathBase;

    std::string mInputRSFile;

    std::string mPackageName;
    std::string mResourceId;
    std::string mPaddingPrefix;

    std::string mClassName;

    std::string mLicenseNote;

    std::string mIndent;

    int mPaddingFieldIndex;

    int mNextExportVarSlot;
    int mNextExportFuncSlot;
    int mNextExportForEachSlot;

    // A mapping from a field in a record type to its index in the rsType
    // instance. Only used when generates TypeClass (ScriptField_*).
    typedef std::map<const RSExportRecordType::Field*, unsigned>
        FieldIndexMapTy;
    FieldIndexMapTy mFieldIndexMap;
    // Field index of current processing TypeClass.
    unsigned mFieldIndex;

    inline void clear() {
      mClassName = "";
      mIndent = "";
      mPaddingFieldIndex = 1;
      mNextExportVarSlot = 0;
      mNextExportFuncSlot = 0;
      mNextExportForEachSlot = 0;
      return;
    }

    bool openClassFile(const std::string &ClassName,
                       std::string &ErrorMsg);

   public:
    typedef enum {
      AM_Public,
      AM_Protected,
      AM_Private,
      AM_PublicSynchronized
    } AccessModifier;

    bool mUseStdout;
    mutable std::ofstream mOF;

    // Generated RS Elements for type-checking code.
    std::set<std::string> mTypesToCheck;

    // Generated FieldPackers for unsigned setters/validation.
    std::set<std::string> mFieldPackerTypes;

    bool addTypeNameForElement(const std::string &TypeName);
    bool addTypeNameForFieldPacker(const std::string &TypeName);

    static const char *AccessModifierStr(AccessModifier AM);

    Context(const std::string &OutputPathBase,
            const std::string &InputRSFile,
            const std::string &PackageName,
            const std::string &ResourceId,
            const std::string &PaddingPrefix,
            bool UseStdout)
        : mVerbose(true),
          mOutputPathBase(OutputPathBase),
          mInputRSFile(InputRSFile),
          mPackageName(PackageName),
          mResourceId(ResourceId),
          mPaddingPrefix(PaddingPrefix),
          mLicenseNote(ApacheLicenseNote),
          mUseStdout(UseStdout) {
      clear();
      resetFieldIndex();
      clearFieldIndexMap();
      return;
    }

    inline std::ostream &out() const {
      return ((mUseStdout) ? std::cout : mOF);
    }
    inline std::ostream &indent() const {
      out() << mIndent;
      return out();
    }

    inline void incIndentLevel() {
      mIndent.append(4, ' ');
      return;
    }

    inline void decIndentLevel() {
      slangAssert(getIndentLevel() > 0 && "No indent");
      mIndent.erase(0, 4);
      return;
    }

    inline int getIndentLevel() { return (mIndent.length() >> 2); }

    inline int getNextExportVarSlot() { return mNextExportVarSlot++; }

    inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
    inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }

    // Will remove later due to field name information is not necessary for
    // C-reflect-to-Java
    inline std::string createPaddingField() {
      return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
    }

    inline void setLicenseNote(const std::string &LicenseNote) {
      mLicenseNote = LicenseNote;
    }

    bool startClass(AccessModifier AM,
                    bool IsStatic,
                    const std::string &ClassName,
                    const char *SuperClassName,
                    std::string &ErrorMsg);
    void endClass();

    void startFunction(AccessModifier AM,
                       bool IsStatic,
                       const char *ReturnType,
                       const std::string &FunctionName,
                       int Argc, ...);

    typedef std::vector<std::pair<std::string, std::string> > ArgTy;
    void startFunction(AccessModifier AM,
                       bool IsStatic,
                       const char *ReturnType,
                       const std::string &FunctionName,
                       const ArgTy &Args);
    void endFunction();

    void startBlock(bool ShouldIndent = false);
    void endBlock();

    inline const std::string &getPackageName() const { return mPackageName; }
    inline const std::string &getClassName() const { return mClassName; }
    inline const std::string &getResourceId() const { return mResourceId; }

    void startTypeClass(const std::string &ClassName);
    void endTypeClass();

    inline void incFieldIndex() { mFieldIndex++; }

    inline void resetFieldIndex() { mFieldIndex = 0; }

    inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
      slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
                  "Nested structure never occurs in C language.");
      mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
    }

    inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
      FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
      slangAssert((I != mFieldIndexMap.end()) &&
                  "Requesting field is out of scope.");
      return I->second;
    }

    inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
  };

  bool genScriptClass(Context &C,
                      const std::string &ClassName,
                      std::string &ErrorMsg);
  void genScriptClassConstructor(Context &C);

  static void genInitBoolExportVariable(Context &C,
                                        const std::string &VarName,
                                        const clang::APValue &Val);
  static void genInitPrimitiveExportVariable(Context &C,
                                             const std::string &VarName,
                                             const clang::APValue &Val);
  static void genInitExportVariable(Context &C,
                                    const RSExportType *ET,
                                    const std::string &VarName,
                                    const clang::APValue &Val);
  static void genInitValue(Context &C, const clang::APValue &Val);
  void genExportVariable(Context &C, const RSExportVar *EV);
  void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
  void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
  void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
  void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
  void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
  void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
  void genPrivateExportVariable(Context &C,
                                const std::string &TypeName,
                                const std::string &VarName);
  void genSetExportVariable(Context &C,
                            const std::string &TypeName,
                            const RSExportVar *EV);
  void genGetExportVariable(Context &C,
                            const std::string &TypeName,
                            const std::string &VarName);

  void genExportFunction(Context &C,
                         const RSExportFunc *EF);

  void genExportForEach(Context &C,
                        const RSExportForEach *EF);

  static void genTypeCheck(Context &C,
                           const RSExportType *ET,
                           const char *VarName);

  static void genTypeInstanceFromPointer(Context &C,
                                         const RSExportType *ET);

  static void genTypeInstance(Context &C,
                              const RSExportType *ET);

  static void genFieldPackerInstance(Context &C,
                                     const RSExportType *ET);

  bool genTypeClass(Context &C,
                    const RSExportRecordType *ERT,
                    std::string &ErrorMsg);
  void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
  void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
  void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
  void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT);
  void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
  void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
  void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
  void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
  void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
  void genTypeClassResize(Context &C);

  void genBuildElement(Context &C,
                       const char *ElementBuilderName,
                       const RSExportRecordType *ERT,
                       const char *RenderScriptVar,
                       bool IsInline);
  void genAddElementToElementBuilder(Context &C,
                                     const RSExportType *ERT,
                                     const std::string &VarName,
                                     const char *ElementBuilderName,
                                     const char *RenderScriptVar,
                                     unsigned ArraySize);
  void genAddPaddingToElementBuiler(Context &C,
                                    int PaddingSize,
                                    const char *ElementBuilderName,
                                    const char *RenderScriptVar);

  bool genCreateFieldPacker(Context &C,
                            const RSExportType *T,
                            const char *FieldPackerName);
  void genPackVarOfType(Context &C,
                        const RSExportType *T,
                        const char *VarName,
                        const char *FieldPackerName);
  void genAllocateVarOfType(Context &C,
                            const RSExportType *T,
                            const std::string &VarName);
  void genNewItemBufferIfNull(Context &C, const char *Index);
  void genNewItemBufferPackerIfNull(Context &C);

 public:
  explicit RSReflection(const RSContext *Context,
      std::vector<std::string> *GeneratedFileNames)
      : mRSContext(Context),
        mLastError(""),
        mGeneratedFileNames(GeneratedFileNames) {
    slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
    return;
  }

  bool reflect(const std::string &OutputPathBase,
               const std::string &OutputPackageName,
               const std::string &InputFileName,
               const std::string &OutputBCFileName);

  inline const char *getLastError() const {
    if (mLastError.empty())
      return NULL;
    else
      return mLastError.c_str();
  }
};  // class RSReflection

}   // namespace slang

#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  NOLINT
