#ifndef TESTHOST_TESTSCENARIO_H_INCLUDED
#define TESTHOST_TESTSCENARIO_H_INCLUDED

#include <JuceHeader.h>
#include "AudioInputSource.h"

/** A timed sequence of actions (MIDI events, parameter changes, patch/bank
	load & save) plus render/I-O configuration, parsed from a JSON file.

	This is what makes test runs repeatable and batchable instead of ad-hoc
	CLI invocations - e.g. one file per regression case, run unattended.
	Nothing in here is JaySynth-specific: events that don't apply to a given
	plugin (MIDI events sent to a plugin with no MIDI input, say) are simply
	harmless, since JUCE's MidiBuffer/AudioProcessor API already tolerates
	that generically.
*/
class TestScenario
{
public:
	TestScenario() {}

	struct Event
	{
		enum Type
		{
			noteOn = 0,
			noteOff,
			controller,
			param,
			loadPatch,
			loadBank,
			savePatch,
			saveBank
		};

		int64 sample = 0;
		Type type = noteOn;

		// MIDI note/controller fields
		int channel = 1;
		int note = 60;
		int velocity = 100;
		int controllerNumber = 0;
		int controllerValue = 0;

		// Parameter-change fields
		int paramIndex = 0;
		float paramValue = 0.0f;

		// Patch/bank load & save fields
		String file;
	};

	/** Parses jsonFile. Relative file paths named inside it (input.wavFile,
		loadPatch/loadBank, and any event's "file") are resolved relative to
		the JSON file's own directory, not the process's working directory,
		so a scenario file is portable regardless of where it's run from.
	*/
	bool loadFromFile (const File &jsonFile);

	double sampleRate = 44100.0;
	int blockSize = 512;
	int64 durationSamples = 0;

	AudioInputSource::Type inputType = AudioInputSource::silence;
	double inputFrequencyHz = 440.0;
	float inputAmplitude = 0.5f;

	String initialLoadPatchFile;
	String initialLoadBankFile;
	String recordWavFile;

	/** Sorted ascending by .sample. */
	Array<Event> events;

private:
	bool parseTopLevel (const var &root, const File &baseDir);
	bool parseInput (const var &inputVar);
	bool parseEvents (const var &eventsVar, const File &baseDir);
	static bool parseEventType (const String &typeName, Event::Type &outType);

	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TestScenario)
};

#endif // TESTHOST_TESTSCENARIO_H_INCLUDED
