/* ======================================================================
   Parts Copyright 2006 University of Leeds, Oxford University, University of the Highlands and Islands.

   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.bodington.util;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.log4j.Logger;

/**
 * Very simple basic virus scanner that uses clamav.
 * @author buckett
 */
public class VirusScanner implements Scanner
{
    
    private static VirusScanner instance = null;
    private static Logger log = Logger.getLogger(VirusScanner.class);
    
    
    /**
     * We want people to use getInstance instead so we can change the 
     * implementation class later.
     */
    private VirusScanner()
    {
    }
    
    /**
     * Gets a Scanner that can be used to scan for viruses.
     * @return A VirusScanner that can be used to scan files.
     */
    public static VirusScanner getInstance()
    {
        if (instance == null)
            instance = new VirusScanner(); 
        return instance;
    }

    /**
     * Scans the passed file.
     * @param source The file to scan.
     * @return The ScannerResults for the scanned file.
     */
    public ScannerResults scan(File source)
    {
        VirusScannerResults results = new VirusScannerResults();
        try
        {
            Process clamscan = Runtime.getRuntime().exec(new String[] {"clamscan", source.getAbsolutePath()});
            int code = clamscan.waitFor();
            switch (code)
            {
                case 0:
                    results.ok = true;
                    break;
                case 1:
                    log.info("Virus Found in: "+ source.getAbsolutePath());
                    results.message = "Virus Found";
                    results.ok = false;
                    break;
                default:
                    log.warn("Unexpected return code from clamscan: "+ code);
            }
        }
        catch (IOException ioe)
        {
            log.warn("Problem starting up clamscan.", ioe);
            results.message = "Could not scan.";
        }
        catch (InterruptedException ie)
        {
            log.warn("Problem waiting for clamscan to finish", ie);
            results.message = "Could not scan.";
        }
        return results;
    }
    
    /**
     * Class to store the results of the scan.
     * @author buckett
     */
    private class VirusScannerResults implements ScannerResults
    {
        boolean ok = false;
        String message;
        
        public boolean isOk()
        {
            return ok;
        }
        
        public List getMessages()
        {
            if (message == null)
                return new ArrayList(0);
            else
                return Arrays.asList(new String[]{message});
        }
    }

}
