'use strict'

const hifo =      require('hifo')
const mergeWith = require('lodash.mergewith')

const tokenize =  require('vbb-util').locations.stations.tokenize

const stations =  require('./data/stations.json')
const tokens =    require('./data/tokens.json')

// naming:
// - a fragment is a part of a search query
// - a token is a part of a stations' name
// - a result is a triple of station, relevance & weight





const findTokensForFragment = function (fragment) {
	let results = []
	for (let token in allTokens) {

		if (token === fragment) // exact match
			results.push({
				name:      fragment,
				relevance: Math.sqrt(fragment.length)
			})

		// match beginning with `fragment`
		else if (fragment === token.slice(0, fragment.length))
			results.push({
				name:      token,
				relevance: fragment.length / token.length
			})
	}
	return results
}

const findStationsForToken = (token) => allTokens[token.name]



const enrichTokenWithStations = (token) => Object.assign(
	token,
	{stations: findStationsForToken(token)}
)

const enrichFragmentWithTokens = (fragment) => ({
	name:   fragment,
	tokens: findTokensForFragment(fragment)
		.map(enrichTokenWithStations)
})









const autocomplete = function (query, limit) {
	let results = hifo(hifo.highest('relevance'), limit || 6)

	let fragments = tokenize(query).split(' ')
		.map(enrichFragmentWithTokens)


				}
			}
		}
	}


	return results.data
}



module.exports = Object.assign(autocomplete, {
	diffFragments,
	findTokensByFragment
})

'use strict'

const hifo =      require('hifo')
const mergeWith = require('lodash.mergewith')

const tokenize =  require('vbb-util').locations.stations.tokenize

const stations =  require('./data/stations.json')
const tokens =    require('./data/tokens.json')

// naming:
// - a fragment is a part of a search query
// - a token is a part of a stations' name
// - a result is a triple of station, relevance & weight





const findTokensForFragment = function (fragment) {
	let results = []
	for (let token in allTokens) {

		if (token === fragment) // exact match
			results.push({
				name:      fragment,
				relevance: Math.sqrt(fragment.length)
			})

		// match beginning with `fragment`
		else if (fragment === token.slice(0, fragment.length))
			results.push({
				name:      token,
				relevance: fragment.length / token.length
			})
	}
	return results
}

const findStationsForToken = (token) => allTokens[token.name]



const enrichTokenWithStations = (token) => Object.assign(
	token,
	{stations: findStationsForToken(token)}
)

const enrichFragmentWithTokens = (fragment) => ({
	name:   fragment,
	tokens: findTokensForFragment(fragment)
		.map(enrichTokenWithStations)
})



const stationsOfToken = (acc, token) => acc.concat(token.stations)
const stationsOfFragment = (fragment) => fragment.tokens
	.reduce(stationsOfToken, [])

const stationMatchesAllFragments = (stationsOfFragments) =>
	(station) => stationsOfFragments
		.every((stationsOfFragment) => stationsOfFragment.indexOf(station) >= 0)

const filterStationsOfFragmentsByAnd = function (fragments) {
	let p = stationMatchesAllFragments(fragments.map(stationsOfFragment))

	for (let fragment of fragments) {
		fragment.tokens = fragment.tokens
			.filter(function (token) {
				token.stations = token.stations.filter(p)
				return token.stations.length > 0
			})
	}
}



const autocomplete = function (query, limit) {
	let results = hifo(hifo.highest('relevance'), limit || 6)

	let fragments = tokenize(query).split(' ')
		.map(enrichFragmentWithTokens)
	filterStationsOfFragmentsByAnd(fragments)


				}
			}
		}
	}


	return results.data
}



module.exports = Object.assign(autocomplete, {
	diffFragments,
	findTokensByFragment
})

rewrite in functional style, part 2