# -*- coding: utf-8 -*-
#! python
from __future__ import with_statement

"""This script reads in the fiat file with data, finds all manually segmented files and creates symlinks
to mfcc and lab files for training data set for HTK. Can be run with mfcc.bash
Arguments: name_of_mfcc_file (no extension) metadata_file
The metadata file is in fiat format; each line describes one utterance.
"""

import os

from gmisclib import die
from gmisclib import fiatio
from gmisclib import dictops
from gmisclib import gpkmisc
# from gmisclib import threaded_io
from gmisclib import nicknames
from gmisclib import wavesurfer_lab as WS

from select_paragraphs import misc

import get_features as GF
import HTK_write as HW
import write_grammar as WG
import phones as PH

MFCC = 'mfcc'
LAB = 'lab'
GRAM = 'gram'
WAV = 'wav'




def a_likely_sequence(phones):
	"""Get rid of alternatives and optionals."""
	assert phones
	o = []
	for p in phones:
		# print '#P.likely=', p, p.likely()
		o.extend( [PH.phone_c(q, s=p.s, e=p.e, dur=p.dur) for q in p.likely()] )
	# assert not (len(o)>2 and o[-1].lbl=='sil' and o[-2].lbl=='sil'), "phones=%s, likely=%s" % (phones, p.likely())
	return tuple(o)


def do_output(info, root, dataid, write_lab_columns, tlf, fnmap, lock, pmap):
	d = os.path.join(info['dbdir'], info['d'], info['f'])

	fncore = info['_uid']
	mfccname = os.path.join(os.path.join(root, MFCC), fncore + '.mfcc')
	try:
		GF.link_mfcc_from_elsewhere(d, mfccname, dataid)
	except GF.NoSuchFileError, x:
		die.warn("Cannot find to link: %s/%s (%s)" % (d,dataid,x))
		return
	except OSError, x:
		with lock:
			die.warn("Link Fails: %s/%s (%s)" % (d,dataid,x))
	wavname = os.path.join(os.path.join(root, WAV), fncore + '.wav')
	try:
		GF.link_wav_from_elsewhere(d, wavname)
	except GF.NoSuchFileError, x:
		die.warn("Cannot find to link: %s/raw.wav (%s)" % (d, x))
		return
	except OSError, x:
		with lock:
			die.warn("Link Fails: %s/raw.wav (%s)" % (d, x))
	with lock:
		tlf.write('%s\n' % mfccname)
	if write_lab_columns:
		fnlab = os.path.join(os.path.join(root, LAB), fncore + '.lab')
		try:
			HW.write_phones(fnlab, a_likely_sequence(info['_phones']), ncol=write_lab_columns)
		except ValueError, x:
			with lock:
				die.info("phones=%s" % info['_phones'])
				die.die("write_phones to %s: error %s" % (fnlab, x))
		except OSError, x:
			with lock:
				die.warn("Write_phones: cannot swap %s" % fnlab)

	fngram = os.path.join(os.path.join(root, GRAM), fncore + '.grammar')
	WG.write_as_alternatives(fngram, info['_phones'])

	infotmp = info.copy()
	infotmp.update({'fncore': fncore, 'fnlab': fncore + '.lab'})
	with lock:
		fnmap.datum(infotmp)



def write_dictionary(root, datalist):
	d = open(os.path.join(root, 'dict'), 'w')
	df = open(os.path.join(root, 'dict_final'), 'w')
	to_be_defined = set()
	for info in datalist:
		for p in info['_phones']:
			for tmp in p.labels():
				to_be_defined.add(tmp)
	for tmp in to_be_defined:
		pm = HW.HTKformat(tmp)
		alt = HW.dict_format(tmp)
		d.write('%s %s\n' % (pm, pm))
		df.write('%s [%s] %s\n' % (pm, alt, pm))

