package jbehave;

import java.util.List;
import java.util.Map;

import org.jbehave.core.model.ExamplesTable;
import org.jbehave.core.model.GivenStories;
import org.jbehave.core.model.Meta;
import org.jbehave.core.model.Narrative;
import org.jbehave.core.model.OutcomesTable;
import org.jbehave.core.model.Scenario;
import org.jbehave.core.model.Story;
import org.jbehave.core.reporters.StoryReporter;

public class StoryReporter2Adapter implements StoryReporter {
	private Story story;
	private Scenario scenario;
	private ExamplesTable examplesTable;
	private Map<String,String> exampleRow;

	private final StoryReporter2 storyReporter2;
	
	public StoryReporter2Adapter(StoryReporter2 storyReporter2) {
		super();
		this.storyReporter2 = storyReporter2;
	}

	@Override
	public void storyNotAllowed(Story story, String filter) {
		storyReporter2.storyNotAllowed(story, filter);
	}

	@Override
	public void beforeStory(Story story, boolean givenStory) {
		this.story = story;
		storyReporter2.beforeStory(story, givenStory);
	}

	@Override
	public void narrative(Narrative narrative) {
		storyReporter2.narrative(story, narrative);
	}

	@Override
	public void afterStory(boolean givenStory) {
		storyReporter2.afterStory(story, givenStory);
		this.story = null;
	}

	@Override
	public void scenarioNotAllowed(Scenario scenario, String filter) {
		storyReporter2.scenarioNotAllowed(story, scenario, filter);
	}

	@Override
	public void beforeScenario(String scenarioTitle) {
		this.scenario = getScenario(scenarioTitle);
		storyReporter2.beforeScenario(story, scenario);
	}

	@Override
	public void scenarioMeta(Meta meta) {
		storyReporter2.scenarioMeta(story, scenario, meta);
	}

	@Override
	public void afterScenario() {
		storyReporter2.afterScenario(story, scenario);
		this.scenario = null;
	}

	@Override
	public void givenStories(GivenStories givenStories) {
		storyReporter2.givenStories(givenStories);
	}

	@Override
	public void givenStories(List<String> storyPaths) {
		storyReporter2.givenStories(storyPaths);
	}

	@Override
	public void beforeExamples(List<String> steps, ExamplesTable table) {
		this.examplesTable = table;
		storyReporter2.beforeExamples(story, scenario, table);
	}

	@Override
	public void example(Map<String, String> exampleRow) {
		if (this.exampleRow != null) {
			// hack an afterExample event
			storyReporter2.afterExample(story, scenario, this.exampleRow);
		}
		storyReporter2.beforeExample(story, scenario, exampleRow);
		this.exampleRow = exampleRow;
	}

	@Override
	public void afterExamples() {
		// hack an afterExample event
		if (this.exampleRow != null) {
			storyReporter2.afterExample(story, scenario, this.exampleRow);
		}
		storyReporter2.afterExamples(story, scenario, examplesTable);
		this.examplesTable = null;
		this.exampleRow = null;
	}

	@Override
	public void successful(String step) {
		storyReporter2.successful(story, scenario, step);
	}

	@Override
	public void ignorable(String step) {
		storyReporter2.ignorable(story, scenario, step);
	}

	@Override
	public void pending(String step) {
		storyReporter2.pending(story, scenario, step);
	}

	@Override
	public void notPerformed(String step) {
		storyReporter2.notPerformed(story, scenario, step);
	}

	@Override
	public void failed(String step, Throwable cause) {
		storyReporter2.failed(story, scenario, step, cause);
	}

	@Override
	public void failedOutcomes(String step, OutcomesTable table) {
		storyReporter2.failedOutcomes(story, scenario, step, table);
	}

	@Override
	public void dryRun() {
		storyReporter2.dryRun();
	}

	@Override
	public void pendingMethods(List<String> methods) {
		storyReporter2.pendingMethods(story, scenario, methods);
	}
	
	protected Scenario getScenario(String scenarioTitle) {
		for (Scenario scenario : story.getScenarios()) {
			if (scenario.getTitle().equals(scenarioTitle)) {
				return scenario;
			}
		}
		throw new IllegalStateException(String.format("No such title %s in story", scenarioTitle));
	}

}
