package ru.bitel.bgbilling.modules.tv.dyn.ares.iptvportal;

import javax.naming.NamingException;

import ru.bitel.bgbilling.apps.tv.access.TvAccess;
import ru.bitel.bgbilling.kernel.container.managed.ServerContext;
import ru.bitel.bgbilling.modules.tv.common.bean.TvDevice;
import ru.bitel.bgbilling.modules.tv.common.event.access.manage.TvDeviceManageEvent;
import ru.bitel.bgbilling.modules.tv.server.bean.TvAccountDao;
import ru.bitel.bgbilling.modules.tv.server.runtime.TvAccountRuntime;
import ru.bitel.bgbilling.modules.tv.server.runtime.TvAccountSpecRuntime;
import ru.bitel.bgbilling.modules.tv.server.runtime.TvAccountSpecRuntimeMap;
import ru.bitel.bgbilling.modules.tv.server.runtime.TvDeviceRuntime;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.ParameterMap;
import ru.bitel.common.Utils;
import ru.bitel.common.sql.ConnectionSet;
import ru.bitel.oss.systems.inventory.resource.common.DeviceManagerMethodType;
import ru.bitel.oss.systems.inventory.resource.common.bean.Device;
import ru.bitel.oss.systems.inventory.resource.common.bean.DeviceType;
import ru.bitel.oss.systems.inventory.resource.common.dm.DeviceManager;
import ru.bitel.oss.systems.inventory.resource.common.dm.DeviceManagerAdapter;
import ru.bitel.oss.systems.inventory.resource.server.DeviceManagerMethod;

public class IptvPortalDeviceManager
	extends DeviceManagerAdapter
	implements DeviceManager
{
	private TvAccess tvAccess;

	@Override
	public Object init( Setup setup, int moduleId, Device<?, ?> device, DeviceType deviceType, ParameterMap deviceConfig )
	{
	    getLogger().info( "init" );

		try
		{
			// <bean name="access" class="ru.bitel.bgbilling.modules.tv.access.TvAccess"/>
			this.tvAccess = (TvAccess)Setup.getEnvironment().lookup( "access" );
		}
		catch( NamingException ex )
		{
		    getLogger().error( ex.getMessage(), ex );
		}

		return null;
	}

	@Override
	public Object destroy()
		throws Exception
	{
	    getLogger().info( "destroy" );

		return null;
	}

	@DeviceManagerMethod(title = "Обновить терминалы из IptvPortal", types = { DeviceManagerMethodType.ACCOUNT })
	public Object terminalsSynchronize( final TvDeviceManageEvent e )
		throws Exception
	{
	    getLogger().info( "terminalsSynchronize" );

		final TvAccountSpecRuntimeMap tvAccountSpecRuntimeMap = tvAccess.getTvAccountSpecRuntimeMap();

		final ServerContext context = ServerContext.get();
		final ConnectionSet connectionSet = context.getConnectionSet();

		final TvDeviceRuntime tvDeviceRuntime = tvAccess.getTvDeviceRuntimeMap().get( e.getDeviceId() );
		final TvDevice tvDevice = tvDeviceRuntime.tvDevice;

		final ParameterMap config = tvDeviceRuntime.config;

		int terminalTvAccountSpecId = config.getInt( "om.terminal.tvAccountSpecId", 0 );
		TvAccountSpecRuntime terminalTvAccountSpecRuntime = tvAccountSpecRuntimeMap.get( terminalTvAccountSpecId );

		final TvAccountRuntime tvAccountRuntime = tvAccess.getTvAccountRuntimeMap().get( e.getAccountId() );
		final TvAccountRuntime parentTvAccountRuntime = tvAccountRuntime.getParentTvAccountRuntime( tvAccess );

		final int subscriberId = Utils.parseInt( parentTvAccountRuntime.getTvAccount().getDeviceAccountId() );

		final TvAccountDao tvAccountDao = new TvAccountDao( connectionSet.getConnection(), tvAccess.moduleId );
		final IptvPortalJsonClient jsonClient = IptvPortalJsonClient.newInstance( tvDevice, config );

		StringBuilder sb = new StringBuilder();
		
		jsonClient.authorize();
		try
		{
			IptvPortalTerminalSynchronizingTask.processAccount( context, connectionSet, tvAccess.moduleId, tvDevice, tvAccountDao,
																terminalTvAccountSpecRuntime, jsonClient, subscriberId, parentTvAccountRuntime.getTvAccount(),
																( s ) -> sb.append( s ) );
		}
		finally
		{
			jsonClient.disconnect();
		}

		sb.append( "\nDone" );

		return sb.toString();
	}
}
