/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.commons.jci2.stores;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.IOUtils;


/**
 * Stores the results on disk
 * 
 * @author tcurdt
 */
public final class FileResourceStore implements ResourceStore {

    private final File root;

    public FileResourceStore( final File pFile ) {
        root = pFile;
    }
    
    public byte[] read( final String pResourceName ) {
        InputStream is = null;
        try {
            is = new FileInputStream(getFile(pResourceName));
            final byte[] data = IOUtils.toByteArray(is);
            return data;
        } catch (final Exception e) {
            return null;
        } finally {
            IOUtils.closeQuietly(is);
        }
    }
    
    public void write( final String pResourceName, final byte[] pData ) {
        OutputStream os = null;
        try {
            final File file = getFile(pResourceName);
            final File parent = file.getParentFile();
            if (!parent.mkdirs() && !parent.isDirectory()) {
                    throw new IOException("could not create" + parent);
            }
            os = new FileOutputStream(file);
            os.write(pData);
        } catch (final Exception e) {
            // FIXME: now what?
        } finally {
            IOUtils.closeQuietly(os);
        }
    }

    public void remove( final String pResourceName ) {
        getFile(pResourceName).delete();
    }

    private File getFile( final String pResourceName ) {
        final String fileName = pResourceName.replace('/', File.separatorChar);
        return new File(root, fileName);
    }

    /**
     * @deprecated
     */
    @Deprecated
    public String[] list() {
        final List<String> files = new ArrayList<String>();
        list(root, files);
        return files.toArray(new String[files.size()]);
    }

    /**
     * @deprecated
     */
    @Deprecated
    private void list(final File pFile, final List<String> pFiles) {
        if (pFile.isDirectory()) {
            final File[] directoryFiles = pFile.listFiles();
            for (final File directoryFile : directoryFiles) {
                list(directoryFile, pFiles);
            }
        } else {
            pFiles.add(pFile.getAbsolutePath().substring(root.getAbsolutePath().length()+1));
        }
    }
    
    @Override
    public String toString() {
        return this.getClass().getName() + root.toString();
    }

}
