package ru.bitel.bgbilling.modules.voice.dyn.mediator.phone;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipInputStream;

import ru.bitel.bgbilling.apps.voice.accounting.mediation.AbstractMediator;
import ru.bitel.bgbilling.apps.voice.accounting.mediation.VoiceRecord;
import ru.bitel.bgbilling.apps.voice.accounting.mediation.VoiceRecordProcessor;
import ru.bitel.bgbilling.modules.voice.server.runtime.VoiceSessionRuntime;
import ru.bitel.common.TimeUtils;
import ru.bitel.common.Utils;

/* TODO переделать на java nio2 и написать unit-тест. Точнее вначале написать unit-Тест, потом переделать 
 * на java.nio2 . Суть unit-теста такая : у нас всего тут Один пока метод public - readHourDataLog - его 
 * тестируем.
 * Надо создать свой файл в тесте,подсунуть сюда и  вместо VoiceRecordProcessor подсунуть свою заглушку
 * (отнаследованную с переопределенными public методами) и потом  проверить с помощью этой заглушки что 
 * считали из этого файла.   
 */
public class DefaultMediator
	extends AbstractMediator
{
	@Override
	public void readHourDataLog( final VoiceRecordProcessor processor, final Date hour )
		throws Exception
	{    			    
        InputStream is = null;
        BufferedReader reader = null;
        
        String path = device.getLogPath();
        
	    try
	    {
            String fullPath = path + TimeUtils.format( hour, "/yyyy/MM/dd_HH" );
    		
    		//TODO переделать чтение на java.nio2 
            File file = new File( fullPath + ".zip" );
    		if ( file.exists() )
    		{
    		    is = new ZipInputStream( new FileInputStream( file ) );
    			((ZipInputStream)is).getNextEntry();
    		}
    		else
    		{
    			file = new File( fullPath );
    			if ( file.exists() )
    			{
    				is = new FileInputStream( file );
    			}
    		}
    		
    		if ( is == null )
    		{
    			logger.warn( "log for " + hour +  " is empty" );
    			return;
    		}
    
    		reader = new BufferedReader( new InputStreamReader( is ), 128 * 1024 );

		    //final Pattern pattern = Pattern.compile( "\\t" );

			String line;
			while( (line = reader.readLine()) != null )
			{
				String[] params = line.split( "\t" );

				if( params.length >= 9 )
				{
					/*if( logger.isDebugEnabled() )
                    {
                        logger.debug( "LINE: " + line );
                    }*/
				    processLine( processor, params );
				}
				else
				{
					logger.warn( "Skip line: " + line );
				}
			}
		}
	    
		finally
		{
			if ( reader != null )
			{
                reader.close();
			}
			
			if ( is != null )
			{
                is.close();
			}
		}
	}

	protected VoiceRecord processLine( final VoiceRecordProcessor processor, final String[] params )
		throws InterruptedException
	{
		final VoiceRecord record = processor.next();
		record.sessionStart = TimeUtils.parseDate( params[0], TimeUtils.DATE_FORMAT_PATTERN_DDMMYYYY_HHMMSS );
		record.duration = record.connectionDuration = Utils.parseInt( params[1], 0 );
		record.callingStationId = params[2].replaceAll( "[^0-9]*", "" );
		record.e164CallingStationId = callingStationIdToE164( params[3] );
		record.calledStationId = params[4].replaceAll( "[^0-9]*", "" );
		record.e164CalledStationId = calledStationIdToE164( params[5] );
		record.trunkIncoming = params[6];
		record.trunkOutgoing = params[7];
		record.category = Utils.parseInt( params[8], 0 );

		if ( params.length > 9 )
		{
			record.connectionDuration = Utils.parseInt( params[9].trim(), 0 );
			try
			{
				record.callCost = new BigDecimal( params[10] );
				record.callOperCost = new BigDecimal( params[11] );
			}
			catch( Exception e )
			{
			}
		}
		
		return record;
	}

	public boolean postSessionCreate( List<VoiceSessionRuntime> recordSessions, VoiceRecord record, boolean abonError, boolean operError )
    {
        return false;
    }
}
