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

#include <cstdio>
#include <list>
#include <string>
#include <utility>
#include <vector>

#include "llvm/ADT/StringMap.h"

#include "slang_rs_reflect_utils.h"
#include "slang_version.h"

// Terrible workaround for TargetOptions.h not using llvm::RefCountedBase!
#include "llvm/ADT/IntrusiveRefCntPtr.h"
using llvm::RefCountedBase;

#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Lex/ModuleLoader.h"

#include "llvm/ADT/StringRef.h"

#include "llvm/Target/TargetMachine.h"

#include "slang_diagnostic_buffer.h"
#include "slang_pragma_list.h"

namespace llvm {
  class tool_output_file;
}

namespace clang {
  class ASTConsumer;
  class ASTContext;
  class Backend;
  class CodeGenOptions;
  class Diagnostic;
  class DiagnosticsEngine;
  class FileManager;
  class FileSystemOptions;
  class HeaderSearchOptions;
  class LangOptions;
  class PCHContainerOperations;
  class Preprocessor;
  class PreprocessorOptions;
  class SourceManager;
  class TargetInfo;
}  // namespace clang

namespace slang {

class RSCCOptions;
class RSContext;
class RSExportRecordType;

llvm::LLVMContext &getGlobalLLVMContext();

class Slang : public clang::ModuleLoader {
 public:
  enum OutputType {
    OT_Dependency,
    OT_Assembly,
    OT_LLVMAssembly,
    OT_Bitcode,
    OT_Nothing,
    OT_Object,

    OT_Default = OT_Bitcode
  };

 private:
  // Language options (define the language feature for compiler such as C99)
  clang::LangOptions LangOpts;
  // Code generation options for the compiler
  clang::CodeGenOptions CodeGenOpts;

  // Returns true if this is a Filterscript file.
  static bool isFilterscript(const char *Filename);

  // Diagnostics Engine (Producer and Diagnostics Reporter)
  clang::DiagnosticsEngine *mDiagEngine;

  // Diagnostics Consumer
  // NOTE: The ownership is taken by mDiagEngine after creation.
  DiagnosticBuffer *mDiagClient;

  // The target being compiled for
  std::shared_ptr<clang::TargetOptions> mTargetOpts;
  std::unique_ptr<clang::TargetInfo> mTarget;
  void createTarget(uint32_t BitWidth);

  // File manager (for prepocessor doing the job such as header file search)
  std::unique_ptr<clang::FileManager> mFileMgr;
  std::unique_ptr<clang::FileSystemOptions> mFileSysOpt;
  void createFileManager();

  // Source manager (responsible for the source code handling)
  std::unique_ptr<clang::SourceManager> mSourceMgr;
  void createSourceManager();

  // Preprocessor (source code preprocessor)
  std::unique_ptr<clang::Preprocessor> mPP;
  void createPreprocessor();

  // AST context (the context to hold long-lived AST nodes)
  std::unique_ptr<clang::ASTContext> mASTContext;
  void createASTContext();

  // AST consumer, responsible for code generation
  std::unique_ptr<clang::ASTConsumer> mBackend;

  // Options for includes
  llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> mHSOpts;

  // Options for the preprocessor (but not header includes)
  llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions> mPPOpts;

  // Module provider (probably not necessary, but keeps us more consistent
  // with regular Clang.
  std::shared_ptr<clang::PCHContainerOperations> mPCHContainerOperations;

  // File names
  std::string mInputFileName;
  std::string mOutputFileName;
  std::string mOutput32FileName;

  std::string mDepOutputFileName;
  std::string mDepTargetBCFileName;
  std::vector<std::string> mAdditionalDepTargets;

  OutputType mOT;

  // Output stream
  std::unique_ptr<llvm::tool_output_file> mOS;

  // Dependency output stream
  std::unique_ptr<llvm::tool_output_file> mDOS;

  std::vector<std::string> mIncludePaths;

  // Context for Renderscript
  RSContext *mRSContext;

  bool mAllowRSPrefix;

  unsigned int mTargetAPI;

  bool mVerbose;

  bool mIsFilterscript;

  // Collect generated filenames (without the .java) for dependency generation
  std::vector<std::string> mGeneratedFileNames;

  PragmaList mPragmas;

  // FIXME: Should be std::list<RSExportable *> here. But currently we only
  //        check ODR on record type.
  //
  // ReflectedDefinitions maps record type name to a pair:
  //  <its RSExportRecordType instance,
  //   the first file contains this record type definition>
  typedef std::pair<RSExportRecordType*, const char*> ReflectedDefinitionTy;
  typedef llvm::StringMap<ReflectedDefinitionTy> ReflectedDefinitionListTy;
  ReflectedDefinitionListTy ReflectedDefinitions;

  bool generateJavaBitcodeAccessor(const std::string &OutputPathBase,
                                   const std::string &PackageName,
                                   const std::string *LicenseNote);

  // CurInputFile is the pointer to a char array holding the input filename
  // and is valid before compile() ends.
  bool checkODR(const char *CurInputFile);

  clang::DiagnosticsEngine &getDiagnostics() { return *mDiagEngine; }
  clang::TargetInfo const &getTargetInfo() const { return *mTarget; }
  clang::FileManager &getFileManager() { return *mFileMgr; }
  clang::SourceManager &getSourceManager() { return *mSourceMgr; }
  clang::Preprocessor &getPreprocessor() { return *mPP; }
  clang::ASTContext &getASTContext() { return *mASTContext; }
  clang::HeaderSearchOptions &getHeaderSearchOpts() { return *mHSOpts; }
  clang::PreprocessorOptions &getPreprocessorOpts() { return *mPPOpts; }

  inline clang::TargetOptions const &getTargetOptions() const
    { return *mTargetOpts.get(); }

  void initPreprocessor();
  void initASTContext();

  clang::ASTConsumer *createBackend(const RSCCOptions &Opts,
                                    const clang::CodeGenOptions &CodeGenOpts,
                                    llvm::raw_ostream *OS,
                                    OutputType OT);

 public:
  static const llvm::StringRef PragmaMetadataName;

  static void GlobalInitialization();

  static bool IsRSHeaderFile(const char *File);
  // FIXME: Determine whether a location is in RS header (i.e., one of the RS
  //        built-in APIs) should only need its names (we need a "list" of RS
  //        built-in APIs).
  static bool IsLocInRSHeaderFile(const clang::SourceLocation &Loc,
                                  const clang::SourceManager &SourceMgr);

  Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine,
        DiagnosticBuffer *DiagClient);

  virtual ~Slang();

  bool setInputSource(llvm::StringRef InputFile);

  std::string const &getInputFileName() const { return mInputFileName; }

  void setIncludePaths(const std::vector<std::string> &IncludePaths) {
    mIncludePaths = IncludePaths;
  }

  void setOutputType(OutputType OT) { mOT = OT; }

  bool setOutput(const char *OutputFile);

  bool setDepOutput(const char *OutputFile);

  void setDepTargetBC(const char *TargetBCFile) {
    mDepTargetBCFileName = TargetBCFile;
  }

  void setAdditionalDepTargets(
      std::vector<std::string> const &AdditionalDepTargets) {
    mAdditionalDepTargets = AdditionalDepTargets;
  }

  void appendGeneratedFileName(std::string const &GeneratedFileName) {
    mGeneratedFileNames.push_back(GeneratedFileName);
  }

  int generateDepFile(bool PhonyTarget);

  int compile(const RSCCOptions &Opts);

  char const *getErrorMessage() { return mDiagClient->str().c_str(); }

  void setDebugMetadataEmission(bool EmitDebug);

  void setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel);

  // Compile bunch of RS files given in the llvm-rs-cc arguments. Return true if
  // all given input files are successfully compiled without errors.
  //
  // @IOFiles - List of pairs of <input file path, output file path>.
  //
  // @DepFiles - List of pairs of <output dep. file path, dependent bitcode
  //             target>. If @OutputDep is true, this parameter must be given
  //             with the same number of pairs given in @IOFiles.
  //
  // @Opts - Selection of options defined from invoking llvm-rs-cc
  bool
  compile(const std::list<std::pair<const char *, const char *>> &IOFiles64,
          const std::list<std::pair<const char *, const char *>> &IOFiles32,
          const std::list<std::pair<const char *, const char *>> &DepFiles,
          const RSCCOptions &Opts,
          clang::DiagnosticOptions &DiagOpts);

  clang::ModuleLoadResult loadModule(clang::SourceLocation ImportLoc,
                                     clang::ModuleIdPath Path,
                                     clang::Module::NameVisibilityKind VK,
                                     bool IsInclusionDirective) override;

  void makeModuleVisible(clang::Module *Mod,
                         clang::Module::NameVisibilityKind Visibility,
                         clang::SourceLocation ImportLoc) override {}

  clang::GlobalModuleIndex *
  loadGlobalModuleIndex(clang::SourceLocation TriggerLoc) override {
    // We don't support C++ modules for RenderScript.
    return nullptr;
  }

  bool lookupMissingImports(llvm::StringRef Name,
                            clang::SourceLocation TriggerLoc) override {
    // We don't support C++ modules for RenderScript.
    return false;
  }
};

} // namespace slang

#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_H_  NOLINT
