/*
 Copyright 2019 Alain Dargelas

 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.
 */

/*
 * File:   PreprocessFile.h
 * Author: alain
 *
 * Created on February 24, 2017, 9:37 PM
 */

#ifndef PREPROCESSFILE_H
#define PREPROCESSFILE_H
#include <string>
#include <vector>
#include <map>
#include <set>
#include <stack>

#include "parser/SV3_1aPpLexer.h"
#include "parser/SV3_1aPpParser.h"
#include "SourceCompile/CompilationUnit.h"
#include "Library/Library.h"
#include "SourceCompile/LoopCheck.h"
#include "SourceCompile/IncludeFileInfo.h"

namespace SURELOG {

class SV3_1aPpTreeShapeListener;
class CompileSourceFile;

#define LINE1 1

/* Can be either an include file or a macro definition being evaluated */
class PreprocessFile {
 public:
  class SpecialInstructions;
  class DescriptiveErrorListener;

  /* Constructors */
  PreprocessFile(SymbolId fileId, CompileSourceFile* csf,
                 SpecialInstructions& instructions,
                 CompilationUnit* compilationUnit, Library* library);
  PreprocessFile(SymbolId fileId, PreprocessFile* includedIn,
                 unsigned int includerLine, CompileSourceFile* csf,
                 SpecialInstructions& instructions,
                 CompilationUnit* compilationUnit, Library* library,
                 std::string macroBody = "", MacroInfo* = NULL,
                 unsigned int embeddedMacroCallLine = 0,
                 SymbolId embeddedMacroCallFile = 0);
  PreprocessFile(const PreprocessFile& orig);
  virtual ~PreprocessFile();

  /* Main function */
  bool preprocess();
  std::string getPreProcessedFileContent();

  /* Macro manipulations */
  void recordMacro(const std::string name, unsigned int line,
                   unsigned short int column,
                   const std::string formal_arguments,
                   const std::vector<std::string> body);
  void recordMacro(const std::string name, unsigned int line,
                   unsigned short int column,
                   const std::vector<std::string> formal_arguments,
                   const std::vector<std::string> body);
  std::string getMacro(const std::string name,
                       std::vector<std::string>& actual_arguments,
                       PreprocessFile* callingFile, unsigned int callingLine,
                       LoopCheck& loopChecker,
                       SpecialInstructions& instructions,
                       unsigned int embeddedMacroCallLine = 0,
                       SymbolId embeddedMacroCallFile = 0);
  bool deleteMacro(const std::string name, std::set<PreprocessFile*>& visited);
  void undefineAllMacros(std::set<PreprocessFile*>& visited);
  bool isMacroBody() { return (m_macroBody != ""); }
  std::string getMacroBody() { return m_macroBody; }
  MacroInfo* getMacroInfo() { return m_macroInfo; }
  SymbolId getMacroSignature();
  const MacroStorage& getMacros() { return m_macros; }
  MacroInfo* getMacro(const std::string name);

  const std::string getFileName(unsigned int line);

  std::string reportIncludeInfo();

  CompileSourceFile* getCompileSourceFile() { return m_compileSourceFile; }
  CompilationUnit* getCompilationUnit() { return m_compilationUnit; }
  Library* getLibrary() { return m_library; }
  antlr4::CommonTokenStream* getTokenStream() {
    return m_antlrParserHandler ? m_antlrParserHandler->m_pptokens : NULL;
  }

  SymbolId getFileId(unsigned int line);
  SymbolId getIncluderFileId(unsigned int line);
  SymbolId getRawFileId() { return m_fileId; }
  unsigned int getLineNb(unsigned int line);
  PreprocessFile* getIncluder() { return m_includer; }
  unsigned int getIncluderLine() { return m_includerLine; }
  unsigned int getLineCount() { return m_lineCount; }
  unsigned int getSumLineCount();
  std::vector<IncludeFileInfo>& getIncludeFileInfo() {
    return m_includeFileInfo;
  }
  IncludeFileInfo& getIncludeFileInfo(int index) {
    if (index >= 0 && index < ((int)m_includeFileInfo.size()))
      return m_includeFileInfo[index];
    else
      return m_badIncludeFileInfo;
  }
  unsigned int getEmbeddedMacroCallLine() { return m_embeddedMacroCallLine; }
  SymbolId getEmbeddedMacroCallFile() { return m_embeddedMacroCallFile; }

  /* Markings */
  static std::string MacroNotDefined;
  static std::string PP__Line__Marking;
  static std::string PP__File__Marking;

 private:
  SymbolId m_fileId;
  Library* m_library;
  std::string m_result;
  std::string m_macroBody;
  PreprocessFile* m_includer;
  unsigned int m_includerLine;
  std::vector<PreprocessFile*> m_includes;
  CompileSourceFile* m_compileSourceFile;
  unsigned int m_lineCount;
  IncludeFileInfo m_badIncludeFileInfo;

 public:
  /* Instructions passed from calling scope */
  class SpecialInstructions {
   public:
    enum TraceInstr : bool { Mute = true, DontMute = false };
    enum EmptyMacroInstr : bool { Mark = true, DontMark = false };
    enum FileLineInfoInstr : bool { Filter = true, DontFilter = false };
    enum CheckLoopInstr : bool { CheckLoop = true, DontCheckLoop = false };
    enum AsIsUndefinedMacroInstr : bool {
      AsIsUndefinedMacro = true,
      ComplainUndefinedMacro = false
    };
    SpecialInstructions()
        : m_mute(DontMute),
          m_mark_empty_macro(DontMark),
          m_filterFileLine(DontFilter),
          m_check_macro_loop(DontCheckLoop),
          m_as_is_undefined_macro(ComplainUndefinedMacro) {}
    SpecialInstructions(SpecialInstructions& rhs)
        : m_mute(rhs.m_mute),
          m_mark_empty_macro(rhs.m_mark_empty_macro),
          m_filterFileLine(rhs.m_filterFileLine),
          m_check_macro_loop(rhs.m_check_macro_loop),
          m_as_is_undefined_macro(rhs.m_as_is_undefined_macro) {}
    SpecialInstructions(TraceInstr mute, EmptyMacroInstr mark_empty_macro,
                        FileLineInfoInstr filterFileLine,
                        CheckLoopInstr check_macro_loop,
                        AsIsUndefinedMacroInstr as_is_undefined_macro)
        : m_mute(mute),
          m_mark_empty_macro(mark_empty_macro),
          m_filterFileLine(filterFileLine),
          m_check_macro_loop(check_macro_loop),
          m_as_is_undefined_macro(as_is_undefined_macro) {}
    void print() {
      std::cout << "Trace:" << (m_mute ? "Mute" : "DontMute")
                << ", EmptyMacro:" << (m_mark_empty_macro ? "Mark" : "DontMark")
                << ", FileLineInfo:"
                << (m_filterFileLine ? "Filter " : "DontFilter")
                << ", CheckLoop:"
                << (m_check_macro_loop ? "CheckLoop" : "DontCheckLoop")
                << ", AsIsUndefMacro:"
                << (m_as_is_undefined_macro ? "AsIsUndefinedMacro"
                                            : "ComplainUndefinedMacro")
                << std::endl;
    };
    TraceInstr m_mute;
    EmptyMacroInstr m_mark_empty_macro;
    FileLineInfoInstr m_filterFileLine;
    CheckLoopInstr m_check_macro_loop;
    AsIsUndefinedMacroInstr m_as_is_undefined_macro;
  };

  std::string evaluateMacroInstance(
      const std::string macro_instance, PreprocessFile* callingFile,
      unsigned int callingLine,
      SpecialInstructions::CheckLoopInstr checkMacroLoop,
      SpecialInstructions::AsIsUndefinedMacroInstr);

  /* Incoming `line handling */
  class LineTranslationInfo {
   public:
    LineTranslationInfo(SymbolId pretendFileId, unsigned int originalLine,
                        unsigned int pretendLine)
        : m_pretendFileId(pretendFileId),
          m_originalLine(originalLine),
          m_pretendLine(pretendLine) {}
    SymbolId m_pretendFileId;
    unsigned int m_originalLine;
    unsigned int m_pretendLine;
  };

  /* `ifdef, `ifndef, `elsif, `else Stack */
  class IfElseItem {
   public:
    enum Type { IFDEF, IFNDEF, ELSIF, ELSE };
    std::string m_macroName;
    bool m_defined;
    Type m_type;
    bool m_previousActiveState;
  };
  typedef std::vector<IfElseItem> IfElseStack;
  IfElseStack m_ifStack;
  IfElseStack& getStack();

  /* Antlr parser container */
  class AntlrParserHandler {
   public:
    AntlrParserHandler()
        : m_inputStream(NULL),
          m_pplexer(NULL),
          m_pptokens(NULL),
          m_ppparser(NULL),
          m_pptree(NULL) {}
    ~AntlrParserHandler();
    antlr4::ANTLRInputStream* m_inputStream;
    SV3_1aPpLexer* m_pplexer;
    antlr4::CommonTokenStream* m_pptokens;
    SV3_1aPpParser* m_ppparser;
    antlr4::tree::ParseTree* m_pptree;
    DescriptiveErrorListener* m_errorListener;
  };
  SV3_1aPpTreeShapeListener* m_listener;

 public:
  /* Options */
  void setDebug(int level);
  bool m_debugPP;
  bool m_debugPPResult;
  bool m_debugPPTokens;
  bool m_debugPPTree;
  bool m_debugMacro;

  SpecialInstructions m_instructions;

  /* To create the preprocessed content */
  void append(const std::string& s);
  void pauseAppend() { m_pauseAppend = true; }
  void resumeAppend() { m_pauseAppend = false; }

  void addLineTranslationInfo(LineTranslationInfo& info) {
    m_lineTranslationVec.push_back(info);
  }

  /* Shorthand for logging an error */
  void addError(Error& error);

  /* Shorthands for symbol manipulations */
  SymbolId registerSymbol(const std::string symbol);
  SymbolId getId(const std::string symbol);
  const std::string getSymbol(SymbolId id);

  // For recursive macro definition detection
  PreprocessFile* getSourceFile();
  LoopCheck m_loopChecker;

  // For cache processing
  void saveCache();
  void collectIncludedFiles(std::set<PreprocessFile*>& included);
  bool usingCachedVersion() { return m_usingCachedVersion; }

 private:
  std::pair<bool, std::string> evaluateMacro_(
      const std::string name, std::vector<std::string>& arguments,
      PreprocessFile* callingFile, unsigned int callingLine,
      LoopCheck& loopChecker, MacroInfo* macroInfo,
      SpecialInstructions& instructions, unsigned int embeddedMacroCallLine,
      SymbolId embeddedMacroCallFile);

  void checkMacroArguments_(const std::string& name, unsigned int line,
                            unsigned short column,
                            const std::vector<std::string>& arguments,
                            const std::vector<std::string>& tokens);
  void forgetPreprocessor_(PreprocessFile*, PreprocessFile* pp);
  AntlrParserHandler* m_antlrParserHandler;

  MacroInfo* m_macroInfo; /* Only used when preprocessing a macro content */
  MacroStorage m_macros;

  CompilationUnit* m_compilationUnit;
  std::vector<LineTranslationInfo> m_lineTranslationVec;
  bool m_pauseAppend;
  bool m_usingCachedVersion;
  std::vector<IncludeFileInfo> m_includeFileInfo;
  unsigned int m_embeddedMacroCallLine;
  SymbolId m_embeddedMacroCallFile;
};

};  // namespace SURELOG

#endif /* PREPROCESSFILE_H */
