/*
 * 
 * Autopsy Forensic Browser
 * 
 * Copyright 2018 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> org
 * 
 * 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.
 */
package org.sleuthkit.autopsy.commonfilesearch;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;

/**
 * Represents that a row in the CR was found in multiple cases. 
 * 
 * Generates a DisplayableItmeNode using a CentralRepositoryFile.
 */
final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttributeInstance {

    private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName());
    private final Integer crFileId;
    private CorrelationAttribute currentAttribute;

    CentralRepoCommonAttributeInstance(Integer attrInstId, Map<Long, AbstractFile> cachedFiles) {
        super(cachedFiles);
        this.crFileId = attrInstId;
    }
    
    void setCurrentAttributeInst(CorrelationAttribute attribute) {
        this.currentAttribute = attribute;
    }

    @Override
    AbstractFile getAbstractFile() {

        Case currentCase;
        if (this.currentAttribute != null) {
            String currentFullPath = this.currentAttribute.getInstances().get(0).getFilePath();
            try {
                currentCase = Case.getCurrentCaseThrows();

                SleuthkitCase tskDb = currentCase.getSleuthkitCase();
                
                File fileFromPath = new File(currentFullPath);
                String fileName = fileFromPath.getName();

                AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s' AND md5 = '%s'", fileName, currentAttribute.getCorrelationValue())).get(0);

                return abstractFile;

            } catch (TskCoreException | NoCurrentCaseException ex) {
                LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s.  Node not created.", new Object[]{currentFullPath}), ex);
                return null;
            }
        }
        return null;
    }

    @Override
    public DisplayableItemNode[] generateNodes() {
        
        // @@@ We should be doing more of this work in teh generateKeys method. We want to do as little as possible in generateNodes
        
        InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor();
        CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId);
        List<DisplayableItemNode> attrInstNodeList = new ArrayList<>(0);
        String currCaseDbName = Case.getCurrentCase().getDisplayName();

        try {
            this.setCurrentAttributeInst(corrAttr);                

            AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile();
            DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createInstance(corrAttr, equivalentAbstractFile, currCaseDbName);
            attrInstNodeList.add(generatedInstNode);

        } catch (TskCoreException ex) {
            LOGGER.log(Level.SEVERE, String.format("Unable to get DataSource for record with md5: %s.  Node not created.", new Object[]{corrAttr.getCorrelationValue()}), ex);
        }

        return attrInstNodeList.toArray(new DisplayableItemNode[attrInstNodeList.size()]);
    }
}

@@ -1362,21 +1362,19 @@
 e cases.
- 
 %0A *
- 
 %0A * Gene
@@ -1900,20 +1900,16 @@
 ;%0A    %7D%0A
-    
 %0A    voi
@@ -2385,32 +2385,16 @@
 Case();%0A
-                
 %0A       
@@ -2499,32 +2499,110 @@
 Path.getName();%0A
+                String parentPath = fileFromPath.getParent() + File.separator;
 %0A               
@@ -2594,32 +2594,37 @@
                 
+List%3C
 AbstractFile abs
@@ -2619,18 +2619,28 @@
 ractFile
- a
+%3E potentialA
 bstractF
@@ -2638,24 +2638,25 @@
 AbstractFile
+s
  = tskDb.fin
@@ -2775,16 +2775,700 @@
 ()))
-.get(0);
+;%0A                AbstractFile finalAbstractFile = null;%0A                for (AbstractFile aFile : potentialAbstractFiles) %7B%0A                    // If a direct match exists, return that and we'll create a CaseDb instance node from it%0A                    if (aFile.getParentPath().equalsIgnoreCase(parentPath)) %7B%0A                        finalAbstractFile = aFile;%0A                        break;%0A                    %7D%0A                %7D%0A                // If not direct match exists, return first md5 match, only used as a backing file for CR instance node.%0A                if (finalAbstractFile == null) %7B%0A                    finalAbstractFile = potentialAbstractFiles.get(0);%0A                %7D
 %0A%0A  
@@ -3488,17 +3488,22 @@
  return 
-a
+finalA
 bstractF
@@ -3895,24 +3895,16 @@
 des() %7B%0A
-        
 %0A       
@@ -4029,25 +4029,16 @@
 teNodes%0A
-        %0A
         
@@ -4431,32 +4431,16 @@
 rrAttr);
-                
 %0A%0A      

Clean logic to return proper AbstractFile, including specific match if one exists.