/*
 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:   CommandLineParser.hpp
 * Author: alain
 *
 * Created on January 26, 2017, 9:47 PM
 */

#ifndef COMMANDLINEPARSER_HPP
#define COMMANDLINEPARSER_HPP
#include <string>
#include <vector>
#include <map>
#include "../SourceCompile/SymbolTable.h"
#include "../ErrorReporting/ErrorContainer.h"

namespace SURELOG {

class CommandLineParser {
 public:
  CommandLineParser(ErrorContainer* errors, SymbolTable* symbolTable,
                    bool diff_comp_mode = false, bool fileUnit = false);
  virtual int parseCommandLine(int argc, const char** argv);
  CommandLineParser(const CommandLineParser& orig);
  virtual ~CommandLineParser();

  /* Verilog command line content */
  const std::vector<SymbolId>& getLibraryPaths() { return m_libraryPaths; }
  const std::vector<SymbolId>& getSourceFiles() { return m_sourceFiles; }
  const std::vector<SymbolId>& getLibraryFiles() { return m_libraryFiles; }
  const std::vector<SymbolId>& getLibraryExtensions() {
    return m_libraryExtensions;
  }
  const std::vector<SymbolId>& getIncludePaths() { return m_includePaths; }
  const std::vector<SymbolId>& getOrdredLibraries() {
    return m_orderedLibraries;
  }
  const std::vector<SymbolId>& getLibraryMapFiles() {
    return m_libraryMapFiles;
  }
  const std::vector<SymbolId>& getConfigFiles() { return m_configFiles; }
  const std::vector<SymbolId>& getUseConfigs() { return m_useConfigs; }
  const std::map<SymbolId, std::string>& getDefineList() {
    return m_defineList;
  }
  bool fileunit() { return m_fileunit; }  // File or all compilation semantic

  /* PP Output file/dir options */
  SymbolId writePpOutputFileId() { return m_writePpOutputFileId; }
  SymbolId getOutputDir() { return m_outputDir; }
  SymbolId getCompileAllDir() { return m_compileAllDirectory; }
  SymbolId getCompileUnitDir() { return m_compileUnitDirectory; }
  SymbolId getCompileDir() {
    return fileunit() ? m_compileUnitDirectory : m_compileAllDirectory;
  }
  SymbolId getFullCompileDir() { return m_fullCompileDir; }
  SymbolId getLogFileId() { return m_logFileId; }
  SymbolId getDefaultLogFileId() { return m_defaultLogFileId; }
  bool writePpOutput() { return m_writePpOutput; }
  bool cacheAllowed() { return m_cacheAllowed; }
  bool lineOffsetsAsComments() { return m_lineOffsetsAsComments; }
  SymbolId getCacheDir() { return m_cacheDirId; }
  SymbolId getPrecompiledDir() { return m_precompiledDirId; }
  bool usePPOutoutFileLocation() { return m_ppOutputFileLocation; }
  /* PP Output content generation options */
  bool filterFileLine() { return m_filterFileLine; }
  bool filterSimpleDirectives() { return m_filterSimpleDirectives; }
  bool filterProtectedRegions() { return m_filterProtectedRegions; }
  bool filterComments() { return m_filterComments; }
  bool filterInfo() { return !m_info; }
  bool filterNote() { return !m_note; }
  bool filterWarning() { return !m_warning; }
  /* Debug/traces options */
  bool muteStdout() { return m_muteStdout; }
  bool verbose() { return m_verbose; }
  bool profile() { return m_profile; }
  int getDebugLevel() { return m_debugLevel; }
  bool getDebugAstModel() { return m_debugAstModel; }
  bool getDebugInstanceTree() { return m_debugInstanceTree; }
  bool getDebugLibraryDef() { return m_debugLibraryDef; }
  bool getDebugIncludeFileInfo() { return m_debugIncludeFileInfo; }
  bool help() { return m_help; }
  void printBanner();
  void printFooter();
  void logBanner(int argc, const char** argv);
  void logFooter();
  static std::string getVersionNumber() { return m_versionNumber; }
  /* Core functions options */
  bool parse() { return m_parse; }
  bool compile() { return m_compile; }
  bool elaborate() { return m_elaborate; }
  bool pythonListener() { return m_pythonListener && m_pythonAllowed; }
  bool pythonAllowed() { return m_pythonAllowed; }

  bool pythonEvalScriptPerFile() {
    return m_pythonEvalScriptPerFile && m_pythonAllowed;
  }
  bool pythonEvalScript() { return m_pythonEvalScript && m_pythonAllowed; }
  SymbolId pythonEvalScriptPerFileId() { return m_pythonEvalScriptPerFileId; }
  SymbolId pythonEvalScriptId() { return m_pythonEvalScriptId; }
  SymbolId pythonListenerId() { return m_pythonListenerFileId; }
  /* Internal */
  ErrorContainer* getErrorContainer() { return m_errors; }
  SymbolTable* getSymbolTable() { return m_symbolTable; }
  unsigned short int getNbMaxTreads() { return m_nbMaxTreads; }
  unsigned int getNbLinesForFileSpliting() { return m_nbLinesForFileSplitting; }
  bool useTbb() { return m_useTbb; }
  std::string getTimeScale() { return m_timescale; }
  bool createCache() { return m_createCache; }
  const std::string currentDateTime();
  bool parseBuiltIn();

 private:
  bool plus_arguments_(const std::string& s);
  void processArgs_(std::vector<std::string>& args,
                    std::vector<std::string>& container);
  void splitPlusArg_(std::string s, std::string prefix,
                     std::vector<SymbolId>& container);
  void splitPlusArg_(std::string s, std::string prefix,
                     std::map<SymbolId, std::string>& container);
  bool checkCommandLine_();
  bool prepareCompilation_(int argc, const char** argv);
  std::vector<SymbolId> m_libraryPaths;          // -y
  std::vector<SymbolId> m_sourceFiles;           // .v .sv
  std::vector<SymbolId> m_libraryFiles;          // -v
  std::vector<SymbolId> m_includePaths;          // +incdir+
  std::vector<SymbolId> m_libraryExtensions;     // +libext+
  std::vector<SymbolId> m_orderedLibraries;      // -L <libName>
  std::vector<SymbolId> m_libraryMapFiles;       // -map
  std::vector<SymbolId> m_configFiles;           // -cfgFile <config file>
  std::vector<SymbolId> m_useConfigs;            // -cfg <configName>
  std::map<SymbolId, std::string> m_defineList;  // +define+
  SymbolId m_writePpOutputFileId;
  bool m_writePpOutput;
  bool m_filterFileLine;
  int m_debugLevel;
  ErrorContainer* m_errors;
  SymbolTable* m_symbolTable;
  SymbolId m_logFileId;
  bool m_lineOffsetsAsComments;
  bool m_liborder;
  bool m_librescan;
  bool m_libverbose;
  bool m_nolibcell;
  bool m_muteStdout;
  bool m_verbose;
  bool m_fileunit;
  bool m_filterSimpleDirectives;
  bool m_filterProtectedRegions;
  bool m_filterComments;
  bool m_parse;
  bool m_compile;
  bool m_elaborate;
  bool m_diff_comp_mode;
  bool m_help;
  bool m_cacheAllowed;
  unsigned short int m_nbMaxTreads;
  SymbolId m_compileUnitDirectory;
  SymbolId m_compileAllDirectory;
  SymbolId m_outputDir;
  SymbolId m_fullCompileDir;
  SymbolId m_defaultLogFileId;
  SymbolId m_defaultCacheDirId;
  SymbolId m_cacheDirId;
  SymbolId m_precompiledDirId;
  static std::string m_versionNumber;
  bool m_note;
  bool m_info;
  bool m_warning;
  bool m_pythonListener;
  bool m_debugAstModel;
  bool m_debugInstanceTree;
  bool m_debugLibraryDef;
  bool m_useTbb;
  bool m_pythonAllowed;
  unsigned int m_nbLinesForFileSplitting;
  std::string m_timescale;
  bool m_pythonEvalScriptPerFile;
  bool m_pythonEvalScript;
  SymbolId m_pythonEvalScriptPerFileId;
  SymbolId m_pythonEvalScriptId;
  SymbolId m_pythonListenerFileId;
  bool m_debugIncludeFileInfo;
  bool m_createCache;
  bool m_profile;
  bool m_parseBuiltIn;
  bool m_ppOutputFileLocation;
  bool m_logFileSpecified;
};

};  // namespace SURELOG

#endif /* COMMANDLINEPARSER_HPP */
