package ru.bitel.bgbilling.modules.inet.dyn.device.rdp;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import ru.bitel.bgbilling.kernel.network.radius.RadiusAttribute;
import ru.bitel.bgbilling.kernel.network.radius.RadiusDictionary;
import ru.bitel.bgbilling.kernel.network.radius.RadiusPacket;
import ru.bitel.bgbilling.modules.inet.common.bean.InetDevice;
import ru.bitel.bgbilling.modules.inet.common.bean.InetDeviceType;
import ru.bitel.bgbilling.modules.inet.common.bean.enums.InetServState;
import ru.bitel.bgbilling.modules.inet.dyn.device.radius.CoAProtocolHandler;
import ru.bitel.bgbilling.modules.inet.server.radius.InetRadiusProcessor;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.ParameterMap;
import ru.bitel.common.Utils;

/**
 * Обработчик для Econat/EcoBRAS.<br>
 * По параметру radius.serviceName.disable определяет, ограничен ли сейчас доступ у сессии или нет.
 */
public class EconatProtocolHandler
    extends CoAProtocolHandler
{
    private static final Logger logger = LogManager.getLogger();

    /**
     * Имя сервиса, при котором доступ отключен.
     */
    protected Set<String> disableServiceNames;

    @Override
    public void init( Setup setup, int moduleId, InetDevice inetDevice, InetDeviceType inetDeviceType, ParameterMap deviceConfig )
        throws Exception
    {
        super.init( setup, moduleId, inetDevice, inetDeviceType, deviceConfig );

        List<String> disableServiceNames = Utils.toList( deviceConfig.get( "radius.serviceName.disable", "" ) );
        if ( disableServiceNames.size() > 0 )
        {
            this.disableServiceNames = Collections.newSetFromMap( new LinkedHashMap<String, Boolean>() );
            this.disableServiceNames.addAll( disableServiceNames );
        }
        else
        {
            this.disableServiceNames = null;
        }

        logger.info( "radius.serviceName.disable=" + this.disableServiceNames );
    }

    @Override
    protected void setStateFromAttributes( RadiusPacket request )
    {
        int acctStatusType = request.getIntAttribute( -1, RadiusDictionary.Acct_Status_Type, -1 );
        if ( acctStatusType != 1 && acctStatusType != 3 ) // проверяем только для стартов и апдейтов
        {
            return;
        }

        logger.debug( "setStateFromAttributes" );

        if ( disableServiceNames != null )
        {
            boolean disabled = false;

            final List<RadiusAttribute<?>> list = request.getAttributes( 9, 251 ); // cisco-SSG-Service-Info
            if ( list != null )
            {
                for ( final RadiusAttribute<?> ra : list )
                {
                    final String value = String.valueOf( ra.getValue() );

                    // сейчас в Eco Service-Info без префикса N, но в будущем может быть с префиксом
                    if ( disableServiceNames.contains( value ) || (value.length() > 1 && value.startsWith( "N" ) && disableServiceNames.contains( value.substring( 1 ) )) )
                    {
                        disabled = true;
                        break;
                    }
                }
            }

            if ( disabled )
            {
                logger.info( "State is disable (from cisco-Service-Info)" );
                request.setOption( InetRadiusProcessor.DEVICE_STATE, InetServState.STATE_DISABLE.getCode() );
            }
            // иначе - enable
            else
            {
                logger.info( "State is enable (from cisco-Service-Info)" );
                request.setOption( InetRadiusProcessor.DEVICE_STATE, InetServState.STATE_ENABLE.getCode() );
            }
        }
        else
        {
            super.setStateFromAttributes( request );
        }
    }
}
