/*
 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:   FileContent.h
 * Author: alain
 *
 * Created on June 8, 2017, 8:22 PM
 */

#ifndef FILECONTENT_H
#define FILECONTENT_H
#include <vector>
#include <map>
#include <unordered_set>
#include "TimeInfo.h"
#include "DesignElement.h"
#include "DesignComponent.h"
#include "ValuedComponentI.h"
#include "VObject.h"
#include "../SourceCompile/VObjectTypes.h"

namespace SURELOG {

class Library;
class ModuleDefinition;
class Package;
class Program;
class ClassDefinition;
class ExprBuilder;
class ErrorContainer; 

typedef std::map<std::string, ModuleDefinition*> ModuleNameModuleDefinitionMap;
typedef std::multimap<std::string, Package*>     PackageNamePackageDefinitionMultiMap;
typedef std::vector<Package*>                    PackageDefinitionVec;
typedef std::map<std::string, Program*>          ProgramNameProgramDefinitionMap;

typedef std::multimap<std::string, ClassDefinition*>  ClassNameClassDefinitionMultiMap;
typedef std::map<std::string, ClassDefinition*>       ClassNameClassDefinitionMap;

class FileContent : public DesignComponent {
public:
    FileContent(SymbolId fileId, Library* library, SymbolTable* symbolTable, ErrorContainer* errors, FileContent* parent, SymbolId fileChunkId) : 
    DesignComponent(NULL), m_fileId(fileId), m_library(library), m_symbolTable(symbolTable), m_errors(errors), m_parentFile(parent), m_fileChunkId(fileChunkId) {} 
    void setLibrary(Library* lib) { m_library = lib; }
    virtual ~FileContent();
    
    typedef std::unordered_map<std::string, NodeId> NameIdMap; 
    
    NodeId sl_get(NodeId parent, VObjectType type);  // Get first child item of type
    
    NodeId sl_parent(NodeId parent, VObjectType type);  // Get first parent item of type
    
    NodeId sl_parent(NodeId parent, std::vector<VObjectType> types, VObjectType& actualType);  // Get first parent item of type
    
    std::vector<NodeId> sl_get_all(NodeId parent, VObjectType type);  // get all child items of type
    
    std::vector<NodeId> sl_get_all(NodeId parent, std::vector<VObjectType>& types);  // get all child items of types
    
    NodeId sl_collect(NodeId parent, VObjectType type); // Recursively search for first item of type
    
    NodeId sl_collect(NodeId parent, VObjectType type, VObjectType stopType); // Recursively search for first item of type
    
    std::vector<NodeId> sl_collect_all(NodeId parent, VObjectType type, bool first = false); // Recursively search for all items of type
    
    std::vector<NodeId> sl_collect_all(NodeId parent, std::vector<VObjectType>& types, bool first = false); // Recursively search for all items of types
    
    std::vector<NodeId> sl_collect_all(NodeId parent, std::vector<VObjectType>& types, std::vector<VObjectType>& stopPoints, bool first = false); 
                                                                                            // Recursively search for all items of types
                                                                                            // and stops at types stopPoints
    unsigned int getSize(); 
    VObjectType  getType() { return VObjectType::slNoType; }
    bool         isInstance() { return false; }
    std::string  getName() { return m_symbolTable->getSymbol(m_fileId); }
    NodeId      getRootNode();
    std::string printObjects(); // The whole file content    
    std::string printSubTree(NodeId parentIndex);  // Print subtree from parent 
    std::vector<std::string> collectSubTree(NodeId uniqueId); // Helper function
    std::string getFileName(NodeId id);
    std::string getChunkFileName() { return m_symbolTable->getSymbol(m_fileChunkId); }
    SymbolTable* getSymbolTable() { return m_symbolTable; }
    void         setSymbolTable(SymbolTable* table) { m_symbolTable = table; }
    SymbolId&    getFileId(NodeId id);
    Library*     getLibrary() { return m_library; }
    std::vector<DesignElement>& getDesignElements() { return m_elements; }
    std::vector<VObject>&       getVObjects() { return m_objects; }
    NameIdMap&                  getObjectLookup() { return m_objectLookup; }
    void                        insertObjectLookup(std::string name, NodeId id, ErrorContainer* errors);
    std::unordered_set<std::string>& getReferencedObjects() { return m_referencedObjects; }
    
    VObject& Object(NodeId index);

    NodeId UniqueId(NodeId index);

    SymbolId& Name(NodeId index);

    NodeId& Child(NodeId index);

    NodeId& Sibling(NodeId index);

    NodeId& Definition(NodeId index);
    
    void SetDefinitionFile(NodeId index, SymbolId def);
    SymbolId GetDefinitionFile(NodeId index);

    NodeId& Parent(NodeId index);
        
    const VObjectType Type(NodeId index);
        
    unsigned int& Line(NodeId index);
    
    std::string SymName(NodeId index) { return m_symbolTable->getSymbol(Name(index)); }
    
    ModuleNameModuleDefinitionMap&   getModuleDefinitions()  { return m_moduleDefinitions; }
    PackageNamePackageDefinitionMultiMap& getPackageDefinitions() { return m_packageDefinitions; }
    ProgramNameProgramDefinitionMap& getProgramDefinitions() { return m_programDefinitions; }
    ClassNameClassDefinitionMultiMap& getClassDefinitions() { return m_classDefinitions; }
    void addModuleDefinition(std::string moduleName, ModuleDefinition* def) {  m_moduleDefinitions.insert(std::make_pair(moduleName, def)) ;}   
    void addPackageDefinition(std::string packageName, Package* package) { m_packageDefinitions.insert(std::make_pair(packageName, package)); }
    void addProgramDefinition(std::string programName, Program* program) { m_programDefinitions.insert(std::make_pair(programName, program)); }
    void addClassDefinition(std::string className, ClassDefinition* classDef) { m_classDefinitions.insert(std::make_pair(className, classDef)); }
    
    ModuleDefinition* getModuleDefinition(const std::string& moduleName);
 
    DesignComponent* getComponentDefinition(const std::string& componentName);
    
    Package* getPackage(const std::string& name);
    
    Program* getProgram(const std::string& name);

    ClassDefinition* getClassDefinition(const std::string& name);
        
    FileContent* getParent() { return m_parentFile; }
    void setParent(FileContent* parent) { m_parentFile = parent; }
    
    std::string getFileName() { return m_symbolTable->getSymbol(m_fileId); }
    
    bool diffTree(std::string& diff, NodeId id, FileContent* oFc, NodeId oId);
    
  private:  
    std::vector<DesignElement> m_elements;
    
    std::vector<VObject>       m_objects;
    std::unordered_map<NodeId, SymbolId> m_definitionFiles;
    
    NameIdMap m_objectLookup; // Populated at ResolveSymbol stage
    std::unordered_set<std::string> m_referencedObjects;
    
    ModuleNameModuleDefinitionMap m_moduleDefinitions;
    
    PackageNamePackageDefinitionMultiMap m_packageDefinitions;
    
    ProgramNameProgramDefinitionMap m_programDefinitions;
    
    ClassNameClassDefinitionMultiMap m_classDefinitions;
    
    SymbolId                   m_fileId;
    Library*                   m_library;
    SymbolTable*               m_symbolTable;
    ErrorContainer*            m_errors;
    FileContent*               m_parentFile; // for file chunks
    SymbolId                   m_fileChunkId;
};

};


#endif /* FILECONTENT_H */


