#ifndef _SLANG_COMPILER_SLANG_HPP
#   define _SLANG_COMPILER_SLANG_HPP

#include "slang_backend.hpp"
#include "slang_rs_context.hpp"
#include "slang_rs_backend.hpp"
#include "slang_pragma_recorder.hpp"
#include "slang_diagnostic_buffer.hpp"

#include <cstdio>
#include <string>

#include "llvm/Support/raw_ostream.h"   /* for class llvm::raw_ostream */

#include "llvm/ADT/OwningPtr.h"         /* for class llvm::OwningPtr */
#include "llvm/ADT/StringRef.h"         /* for class llvm::StringRef */

#include "clang/AST/ASTConsumer.h"      /* for class clang::ASTConsumer */
#include "clang/AST/ASTContext.h"       /* for class clang::ASTContext */

#include "clang/Lex/Preprocessor.h"     /* for class clang::Preprocessor */
#include "clang/Lex/HeaderSearch.h"     /* for class clang::HeaderSearch */

#include "clang/Basic/Diagnostic.h"     /* for class clang::Diagnostic, class clang::DiagnosticClient, class clang::DiagnosticInfo  */
#include "clang/Basic/FileManager.h"    /* for class clang::FileManager and class clang::FileEntry */
#include "clang/Basic/TargetOptions.h"  /* for class clang::TargetOptions */

namespace llvm {

class Twine;
class TargetInfo;

}   /* namespace llvm */

namespace clang {

class LangOptions;
class CodeGenOptions;

}   /* namespace clang */

namespace slang {

using namespace clang;

class Slang {
    static LangOptions LangOpts;
    static CodeGenOptions CodeGenOpts;

    static bool GlobalInitialized;

    static void GlobalInitialization();

    static void LLVMErrorHandler(void *UserData, const std::string &Message);

private:
    PragmaList mPragmas;

    /* The diagnostics engine instance (for status reporting during compilation) */
    llvm::OwningPtr<Diagnostic> mDiagnostics;

    llvm::OwningPtr<DiagnosticBuffer> mDiagClient;
    inline void createDiagnostic() {
        mDiagClient.reset(new DiagnosticBuffer());
        mDiagnostics.reset(new Diagnostic(mDiagClient.get()));
        bool optionNotFound = mDiagnostics->setDiagnosticGroupMapping("implicit-function-declaration", clang::diag::MAP_ERROR);
        assert(!optionNotFound && "Unable find option group implicit-function-declaration");
        return;
    }

    /* The target being compiled for */
    TargetOptions mTargetOpts;
    llvm::OwningPtr<TargetInfo> mTarget;
    void createTarget(const char* Triple, const char* CPU, const char** Features);

    /**** Below is for parsing ****/

    /* The file manager (for prepocessor doing the job such as header file search) */
    llvm::OwningPtr<FileManager> mFileMgr;
    inline void createFileManager() { mFileMgr.reset(new FileManager()); return; }

    /* The source manager (responsible for the source code handling) */
    llvm::OwningPtr<SourceManager> mSourceMgr;  /* The source manager */
    inline void createSourceManager() { mSourceMgr.reset(new SourceManager(*mDiagnostics)); return; }

    /* The preprocessor (source code preprocessor) */
    llvm::OwningPtr<Preprocessor> mPP;
    void createPreprocessor();

    /* The AST context (the context to hold long-lived AST nodes) */
    llvm::OwningPtr<ASTContext> mASTContext;
    inline void createASTContext() {
        mASTContext.reset(new ASTContext(LangOpts,
                                         *mSourceMgr,
                                         *mTarget,
                                         mPP->getIdentifierTable(),
                                         mPP->getSelectorTable(),
                                         mPP->getBuiltinInfo()));
        return;
    }

    /* Context for RenderScript */
    llvm::OwningPtr<RSContext> mRSContext;
    inline void createRSContext() {
        mRSContext.reset(new RSContext(mPP.get(),
                                       mASTContext.get(),
                                       mTarget.get()));
        return;
    }

    /* The AST consumer, responsible for code generation */
    llvm::OwningPtr<Backend> mBackend;
    inline void createBackend() {
        mBackend.reset(new Backend(*mDiagnostics,
                                   CodeGenOpts,
                                   mTargetOpts,
                                   mPragmas,
                                   mOS.take(),
                                   mOutputType,
                                   *mSourceMgr,
                                   mAllowRSPrefix));

        return;
    }

    inline void createRSBackend() {
        mBackend.reset(new RSBackend(mRSContext.get(),
                                     *mDiagnostics,
                                     CodeGenOpts,
                                     mTargetOpts,
                                     mPragmas,
                                     mOS.take(),
                                     mOutputType,
                                     *mSourceMgr,
                                     mAllowRSPrefix));

        return;
    }

    /* Input file name */
    std::string mInputFileName;
    std::string mOutputFileName;

    SlangCompilerOutputTy mOutputType;

    /* Output stream */
    llvm::OwningPtr<llvm::raw_ostream> mOS;

    bool mAllowRSPrefix;

public:
    static const std::string TargetDescription;

    static const llvm::Twine PragmaMetadataName;

    Slang(const char* Triple, const char* CPU, const char** Features);

    bool setInputSource(llvm::StringRef inputFile, const char* text, size_t textLength);

    bool setInputSource(llvm::StringRef inputFile);

    void setOutputType(SlangCompilerOutputTy outputType);

    inline bool setOutput(FILE* stream) {
        if(stream == NULL)
            return false;

        mOS.reset( new llvm::raw_fd_ostream(fileno(stream), /* shouldClose */false) );
        return true;
    }

    bool setOutput(const char* outputFile);

    inline void allowRSPrefix() {
        mAllowRSPrefix = true;
    }

    int compile();

    bool reflectToJava(const char* outputPackageName);
    bool reflectToJavaPath(const char* outputPathName);

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

    void getPragmas(size_t* actualStringCount, size_t maxStringCount, char** strings);

    /* Reset the slang compiler state such that it can be reused to compile another file */
    inline void reset() {
        /* Seems there's no way to clear the diagnostics. We just re-create it. */
        createDiagnostic();
        mOutputType = SlangCompilerOutput_Default;
        return;
    }

    ~Slang();
};  /* class Slang */

}   /* namespace slang */

#endif  /* _SLANG_COMPILER_SLANG_HPP */
