/**
 * Copyright (C) 2011
 *   Michael Mosmann <michael@mosmann.de>
 *   Martin Jöhren <m.joehren@googlemail.com>
 *
 * with contributions from
 * 	konstantin-ba@github,Archimedes Trajano (trajano@github)
 *
 * 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 de.flapdoodle.embed.process.extract;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import de.flapdoodle.embed.process.config.store.FileSet;
import de.flapdoodle.embed.process.config.store.FileType;
import de.flapdoodle.embed.process.config.store.FileSet.Entry;
import de.flapdoodle.embed.process.io.directories.IDirectory;
import de.flapdoodle.embed.process.io.file.FileAlreadyExistsException;
import de.flapdoodle.embed.process.io.file.Files;

public class FilesToExtract {

	private final ArrayList<FileSet.Entry> _files;
	private final ITempNaming _exeutableNaming;
	private final File _dirFactoryResult;
	private final boolean _dirFactoryResultIsGenerated;

	public FilesToExtract(IDirectory dirFactory, ITempNaming exeutableNaming, FileSet fileSet) {
		if (dirFactory==null) throw new NullPointerException("dirFactory is NULL");
		if (exeutableNaming==null) throw new NullPointerException("exeutableNaming is NULL");
		if (fileSet==null) throw new NullPointerException("fileSet is NULL");
		
		_files = new ArrayList<FileSet.Entry>(fileSet.entries());
		_dirFactoryResult = dirFactory.asFile();
		_dirFactoryResultIsGenerated=dirFactory.isGenerated();
		_exeutableNaming = exeutableNaming;
	}

	public File generatedBaseDir() {
		return _dirFactoryResultIsGenerated ? _dirFactoryResult : null;
	}
	
	public boolean nothingLeft() {
		return _files.isEmpty();
	}

	public IExtractionMatch find(IArchiveEntry entry) {
		Entry found = null;

		if (!entry.isDirectory()) {
			for (FileSet.Entry e : _files) {
				if (e.matchingPattern().matcher(entry.getName()).matches()) {
					found = e;
					break;
				}
			}

			if (found != null) {
				_files.remove(found);
			}
		}
		return found!=null ? new Match(_dirFactoryResult,_exeutableNaming, found) : null;
	}
	
	static class Match implements IExtractionMatch {

		private final Entry _entry;
		private final File _dirFactoryResult;
		private final ITempNaming _exeutableNaming;

		public Match(File dirFactoryResult,ITempNaming exeutableNaming, Entry entry) {
			_dirFactoryResult = dirFactoryResult;
			_exeutableNaming = exeutableNaming;
			_entry = entry;
		}
		
		@Override
		public FileType type() {
			return _entry.type();
		}

		@Override
		public File write(InputStream source, long size) throws IOException {
			File destination;
			switch (_entry.type()) {
				case Executable: 
					try {
						destination=Files.createTempFile(_dirFactoryResult,_exeutableNaming.nameFor("extract",_entry.destination()));
					} catch (FileAlreadyExistsException ex) {
						throw new ExecutableFileAlreadyExistsException(ex);
					}
					break;
				default:
					destination=Files.createTempFile(_dirFactoryResult,_entry.destination());
					break;
			}
			
			Files.write(source, size, destination);
			switch (_entry.type()) {
				case Executable:
					destination.setExecutable(true);
					break;
			}
			return destination;
		}
		
	}


}

@@ -1380,32 +1380,33 @@
 ITempNaming _exe
+c
 utableNaming;%0A%09p
@@ -1549,32 +1549,33 @@
  ITempNaming exe
+c
 utableNaming, Fi
@@ -1678,16 +1678,17 @@
 %09if (exe
+c
 utableNa
@@ -1734,16 +1734,17 @@
 ion(%22exe
+c
 utableNa
@@ -1996,24 +1996,25 @@
 ed();%0A%09%09_exe
+c
 utableNaming
@@ -2011,32 +2011,33 @@
 ableNaming = exe
+c
 utableNaming;%0A%09%7D
@@ -2560,32 +2560,33 @@
 ctoryResult,_exe
+c
 utableNaming, fo
@@ -2752,24 +2752,25 @@
 pNaming _exe
+c
 utableNaming
@@ -2820,24 +2820,25 @@
 mpNaming exe
+c
 utableNaming
@@ -2898,24 +2898,25 @@
 ult;%0A%09%09%09_exe
+c
 utableNaming
@@ -2921,16 +2921,17 @@
 ng = exe
+c
 utableNa
@@ -3258,16 +3258,17 @@
 ult,_exe
+c
 utableNa

Fix spelling of executable