# -*- 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
import sys
# import dummy_threading as _threading

from gmisclib import die
from gmisclib import fiatio
from gmisclib import dictops
from gmisclib import gpkmisc
from gmisclib import load_mod
from gmisclib import g_encode
from gmisclib import threaded_io
from gmisclib import wavesurfer_lab as WS

from select_paragraphs import misc

sys.path.insert(0, 'lib')
import process_phones as PRP
import HTK_write as HW
import generate as GE
import generate_misc as GM
import get_phones as GP

Vfile = '/proj/aesop/select_paragraphs/List_of_phones.txt'



def run(dataid, metadatafilenames, mapname, root, rec):
	REC = load_mod.load('generate_special', [rec])
	print '# Using specializations from ', REC.__file__
	assert metadatafilenames
	phonology = misc.read_phone_props(Vfile)
	pmap = PRP.make_pmap(phonology, mapname)

	datalist = []
	for mdfn in metadatafilenames:
		metadatafile = open(mdfn, 'r')
		data = REC.read_VY(metadatafile)
		metadatafile.close()
		if len(data) == 0:
			die.warn("Odd: no data in %s" % mdfn)
		datalist.extend( REC.select_VY_datalist(data) )
	assert len(datalist) > 0

	gpkmisc.makedirs(os.path.join(root, GE.LAB))
	gpkmisc.makedirs(os.path.join(root, GE.MFCC))
	gpkmisc.makedirs(os.path.join(root, GE.GRAM))
	gpkmisc.makedirs(os.path.join(root, GE.WAV))
	fnmap = fiatio.writer(open(os.path.join(root, 'metadata.fiat'), 'w'))
	fnmap.comment("This is a secondary metadata file, created during the ASR operation.")
	fnmap.comment("It is a copy of the following files, with added info on names used by the ASR system.")
	for mdfn in metadatafilenames:
		fnmap.comment(mdfn)
	odatalist = []
	for (i,info) in enumerate(datalist):
		try:
			phonelists = REC.prepare_VY_phones(info, pmap, phonology)
		except IOError, x:
			die.warn("Cannot read %s/%s/%s: %s" % (info['dbdir'], info['d'], info['f'], x))
			continue
		except GM.BadPhonesError, x:
			die.warn("%s in %s/%s/%s" % (x, info['dbdir'], info['d'], info['f']))
			continue
		except GP.NotInLexicon, x:
			die.warn("NotInLexicon: %s (%s/%s/%s)" % (x, info['dbdir'], info['d'], info['f']))
			continue
		if len(phonelists) == 0:
			continue
		assert len(phonelists)==1
		if GM.occasionally(i):
			die.info("Phonelist=%s" % str(phonelists[0]))
		# Be aware that prepare_phones() can return more than one
		# alternative transcription, such as when there are several
		# human transcribers.   In such a case, we use them all.
		for (i,phones) in enumerate(phonelists):
			tmp = info.copy()
			assert phones
			tmp['_phones'] = phones
			tmp['_uid'] = '%s,%s,%d' % (info['d'], info['f'], i)
			# if SU.selected_VY(tmp, whichpass):
			if REC.selected(tmp):
				odatalist.append(tmp)
			else:
				die.info("%s.selected() rejected phonelist" % REC.__file__)
	assert odatalist
	odatalist, allphones = PRP.merge_rare_phones(odatalist, REC.MIN_VY_PHONE_FREQ)
	HW.write_phonemap(root, allphones)
	GE.write_dictionary(root, odatalist)

	nn = GM.make_nicknames([info['_uid'] for info in odatalist])
	for info in odatalist:
		info['_uid'] = nn[info['_uid']]
	tlf = open(os.path.join(root, 'trainlist'), 'w')
	tpl = threaded_io.Lock()
	# tpl = _threading.Lock()
	tp = threaded_io.Thread_poolW(5)
	for info in odatalist:
		tp.start(GE.do_output, args=(info, root, dataid, 1, tlf, fnmap, tpl, pmap))
		# GE.do_output(info, root, dataid, 1, tlf, fnmap, tpl, pmap)
	tp.join()




if __name__ == '__main__':
	dataid = sys.argv[1]
	root = sys.argv[2]
	metadatafilenames = sys.argv[5:]
	# run(mfcc, metadatafilenames, 'VorC', root)
	rec = sys.argv[3]
	modeltype = sys.argv[4]
	run(dataid, metadatafilenames, modeltype, root, rec)
