package foodchain

import (
	"fmt"
	"strings"
)

// TestVersion is an exercism thing
const TestVersion = 1

// An Inedible is something that you probably shouldn't eat.
// At the least, you shouldn't eat it whole/live.
type Inedible struct {
	// What it is
	Name string
	// A quick jab about it
	FollowUp string
}

// DoNotEat is a non-exhaustive list of Inedibles. It's recommended
// that you don't eat them. Yet the old lady did.
var DoNotEat = []Inedible{
	Inedible{
		"fly", "I don't know why she swallowed the fly. Perhaps she'll die.",
	},
	Inedible{
		"spider", "It wriggled and jiggled and tickled inside her.",
	},
	Inedible{
		"bird", "How absurd to swallow a bird!",
	},
	Inedible{
		"cat", "Imagine that, to swallow a cat!",
	},
	Inedible{
		"dog", "What a hog, to swallow a dog!",
	},
	Inedible{
		"goat", "Just opened her throat and swallowed a goat!",
	},
	Inedible{
		"cow", "I don't know how she swallowed a cow!",
	},
	Inedible{
		"horse", "She's dead, of course!",
	},
}

// Verse generates the text for a specific verse
func Verse(verseNum int) string {
	return strings.Trim(Swallow(verseNum-1, true), "\n")
}

// Verses generates the text for all verses from verse1 to verse2
func Verses(verse1, verse2 int) string {
	var ret string
	for verse1 <= verse2 {
		ret += Verse(verse1) + "\n\n"
		verse1++
	}
	return strings.Trim(ret, "\n")
}

// Song generates all verses
func Song() string {
	var ret string
	for verseNum := 1; verseNum <= len(DoNotEat); verseNum++ {
		ret += Verse(verseNum) + "\n\n"
	}
	return strings.Trim(ret, "\n")
}

// Swallow generates the text for swallowing something
func Swallow(dneIdx int, first bool) string {
	var ret string

	if first || dneIdx == len(DoNotEat)-1 {
		ret = fmt.Sprintf(
			"I know an old lady who swallowed a %s.\n%s\n",
			DoNotEat[dneIdx].Name,
			DoNotEat[dneIdx].FollowUp,
		)
		if dneIdx == 0 || dneIdx == len(DoNotEat)-1 {
			return ret
		}
	}
	ret += fmt.Sprintf("She swallowed the %s to catch the %s",
		DoNotEat[dneIdx].Name,
		DoNotEat[dneIdx-1].Name,
	)
	if DoNotEat[dneIdx-1].Name == "spider" {
		ret += " that wriggled and jiggled and tickled inside her.\n"
	} else if DoNotEat[dneIdx-1].Name == "fly" {
		ret += ".\nI don't know why she swallowed the fly. Perhaps she'll die.\n"
		return ret
	} else {
		ret += ".\n"
	}
	return ret + Swallow(dneIdx-1, false)
}
