/*
 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 "CompilationUnit.h"
#include "../Library/Library.h"
#include "LoopCheck.h"
#include "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;
};

};

#endif /* PREPROCESSFILE_H */




