package es.uniovi.reflection.patternmining.visitor.file;

import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreeScanner;

import es.uniovi.reflection.patternmining.features.FileFeatures;
import es.uniovi.reflection.patternmining.features.TypeDefFeatures;
import es.uniovi.reflection.patternmining.model.ReturnFeatures;
import es.uniovi.reflection.patternmining.util.Util;

public class FilesVisitor extends TreeScanner<ReturnFeatures, FileFeatures>{
	
	
	@Override
    public ReturnFeatures visitCompilationUnit(CompilationUnitTree compilationUnitTree, FileFeatures fileFeatures) {
		
		fileFeatures.setFilePathName(compilationUnitTree.getSourceFile().getName().toString());
		
	    try {
			fileFeatures.setId(Util.databaseService.insertFile(fileFeatures));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
		}
	   
	    ReturnFeatures returnProgramFeatures=new ReturnFeatures();
	  
	      fileFeatures.setHeight(0);
	      
	      try {
	    	  fileFeatures.setPackageName(compilationUnitTree.getPackageName().toString() + ".");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				fileFeatures.setPackageName("");
				
			}
	      
	      
	      for(Tree ct: compilationUnitTree.getTypeDecls()) {
	    	  ReturnFeatures returnFeatures = ct.accept(this, fileFeatures);
	    	  if (returnFeatures != null) {
		    	  returnProgramFeatures.setNumberOfClasses(returnProgramFeatures.getNumberOfClasses() + returnFeatures.getNumberOfClasses());
		          returnProgramFeatures.setNumberOfInterfaces(returnProgramFeatures.getNumberOfInterfaces() + returnFeatures.getNumberOfInterfaces());
		          returnProgramFeatures.setNumberOfEnums(returnProgramFeatures.getNumberOfEnums() + returnFeatures.getNumberOfEnums());   
		          returnProgramFeatures.setNumberOfTypesInDefaultPackage(returnProgramFeatures.getNumberOfTypesInDefaultPackage() + returnFeatures.getNumberOfTypesInDefaultPackage());
		          returnProgramFeatures.setNumberOfTypesInPackages(returnProgramFeatures.getNumberOfTypesInPackages() + returnFeatures.getNumberOfTypesInPackages());		          
	    	  }  
	      }
	      
	      return returnProgramFeatures;
    }
	
	@Override
    public ReturnFeatures visitClass(ClassTree classTree, FileFeatures fileFeatures) {
        TypeDefFeatures typeDefFeatures = new TypeDefFeatures();
        typeDefFeatures.setFileId(fileFeatures.getId());
        Util.fileId = typeDefFeatures.getFileId();
        typeDefFeatures.setParentId(Util.getNextNodeId());//to save in the database
        typeDefFeatures.setHeight(fileFeatures.getHeight());
        typeDefFeatures.setPackageName(fileFeatures.getPackageName());
        
        //devolvemos las estadisticas del type definition
        return Util.visitors.getVisitorTypeDefs().visitClass(classTree, typeDefFeatures);
    }
}
