class SetChordProgressionEvent implements IEventChain {

    @Override
    public QueueState set(QueueState queueState) {
        ChordMelodyDecoder decoder = new ChordMelodyDecoder(null);
        KeyExtractor keyExtractor = new KeyExtractor();

        String encodedKey = getRandomKey();
        String decodedKey = decoder.getNoteName(encodedKey);

        List<HiveChord> chords = keyExtractor.getChordsInKey(decodedKey);

        HiveChord chordOne = chords.get((new Random().nextInt(chords.size())));
        HiveChord chordTwo = chords.get((new Random().nextInt(chords.size())));

        List<String> verseChords = getChordForProgressionUnit(encodedKey, chordOne, chordTwo, queueState.getAppRoot());
        List<HiveChord> verseHiveChords = verseChords.stream().map(c -> new HiveChord(c)).collect(Collectors.toList());

        List<String> chorusChords = getChordForProgressionUnit(encodedKey, new HiveChord(verseChords.get(2)), new HiveChord(verseChords.get(3)), queueState.getAppRoot());
        List<HiveChord> chorusHiveChords = chorusChords.stream().map(c -> new HiveChord(c)).collect(Collectors.toList());

        List<String> bridgeChords = getChordForProgressionUnit(encodedKey, new HiveChord(chorusChords.get(2)), new HiveChord(chorusChords.get(3)), queueState.getAppRoot());
        List<HiveChord> bridgeHiveChords = bridgeChords.stream().map(c -> new HiveChord(c)).collect(Collectors.toList());

        for(ProgressionUnit progressionUnit : queueState.getStructure()){
            ProgressionUnit.ProgressionType type = progressionUnit.getType();

            switch (type) {
                case VERSE:
                    for (int i = 0; i < progressionUnit.getProgressionUnitBars().size(); i++) {
                        progressionUnit.getProgressionUnitBars().get(i).setChord(verseHiveChords.get(i));
                    }
                    break;
                case CHORUS:
                    for (int i = 0; i < progressionUnit.getProgressionUnitBars().size(); i++) {
                        progressionUnit.getProgressionUnitBars().get(i).setChord(chorusHiveChords.get(i));
                    }
                    break;
                case BRIDGE:
                    for (int i = 0; i < progressionUnit.getProgressionUnitBars().size(); i++) {
                        progressionUnit.getProgressionUnitBars().get(i).setChord(bridgeHiveChords.get(i));
                    }
                    break;
                default:
                    throw new RuntimeException("unexpected progression unit type");
            }
        }

        return queueState;
    }

}