/*
 * Copyright 2010 david varnes.
 *
 * Licensed under the Apache License, version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at:
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.freeswitch.esl.client.outbound.example;

import org.freeswitch.esl.client.outbound.AbstractOutboundClientHandler;
import org.freeswitch.esl.client.transport.SendMsg;
import org.freeswitch.esl.client.transport.event.EslEvent;
import org.freeswitch.esl.client.transport.message.EslMessage;
import org.freeswitch.esl.client.transport.message.EslHeaders.Name;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;

/**
 * Simple example of a handler for outbound connection from FreeSWITCH server.
 * This class will log some of the FreeSWTICH call channel variables and then
 * hangup the call.
 * 
 * @author david varnes
 */
public class SimpleHangupOutboundHandler extends AbstractOutboundClientHandler {

    @Override
    protected void handleConnectResponse(ChannelHandlerContext ctx, EslEvent event) {
        log.info("Received connect response [{}]", event);
        if (event.getEventName().equalsIgnoreCase("CHANNEL_DATA")) {
            // this is the response to the initial connect
            log.info("=======================  incoming channel data  =============================");
            log.info("Event-Date-Local: [{}]", event.getEventDateLocal());
            log.info("Unique-ID: [{}]", event.getEventHeaders().get("Unique-ID"));
            log.info("Channel-ANI: [{}]", event.getEventHeaders().get("Channel-ANI"));
            log.info("Answer-State: [{}]", event.getEventHeaders().get("Answer-State"));
            log.info("Caller-Destination-Number: [{}]", event.getEventHeaders().get("Caller-Destination-Number"));
            log.info("=======================  = = = = = = = = = = =  =============================");

            String legAuuid = event.getEventHeaders().get("Unique-ID");

            // answer call
            answerCall(ctx.getChannel(), legAuuid);

            // bridge call
            bridgeCall(ctx.getChannel());

            // record audio
            recordCall(ctx.getChannel());

            // eavesdrop
            eavesdropCall(ctx.getChannel(), legAuuid);

        } else {
            throw new IllegalStateException("Unexpected event after connect: [" + event.getEventName() + ']');
        }
    }

    @Override
    protected void handleEslEvent(ChannelHandlerContext ctx, EslEvent event) {
        log.info("Received event [{}]", event);
    }

    private void answerCall(Channel channel, String uuid) {
        SendMsg answerMsg = new SendMsg(uuid);
        answerMsg.addCallCommand("execute");
        answerMsg.addExecuteAppName("answer");

        EslMessage response = sendSyncMultiLineCommand(channel, answerMsg.getMsgLines());
        if (response.getHeaderValue(Name.REPLY_TEXT).startsWith("+OK")) {
            log.info("Call answered succesfully");
        } else {
            log.error("Call answer failed: [{}}", response.getHeaderValue(Name.REPLY_TEXT));
        }
    }

    private void bridgeCall(Channel channel) {
        SendMsg bridgeMsg = new SendMsg();
        bridgeMsg.addCallCommand("execute");
        bridgeMsg.addExecuteAppName("bridge");
        bridgeMsg.addExecuteAppArg("sofia/internal/5562@192.168.23.104");

        EslMessage response = sendSyncMultiLineCommand(channel, bridgeMsg.getMsgLines());

        if (response.getHeaderValue(Name.REPLY_TEXT).startsWith("+OK")) {
            log.info("Call bridge successful");
        } else {
            log.error("Call bridge failed: [{}}", response.getHeaderValue(Name.REPLY_TEXT));
        }
    }

    private void recordCall(Channel channel) {
        SendMsg recordMsg = new SendMsg();
        recordMsg.addCallCommand("execute");
        recordMsg.addExecuteAppName("record");
        recordMsg.addExecuteAppArg("/tmp/recording.wav");

        EslMessage response = sendSyncMultiLineCommand(channel, recordMsg.getMsgLines());

        if (response.getHeaderValue(Name.REPLY_TEXT).startsWith("+OK")) {
            log.info("Call record successful");
        } else {
            log.error("Call record failed: [{}}", response.getHeaderValue(Name.REPLY_TEXT));
        }
    }

    private void eavesdropCall(Channel channel, String uuid) {

        sendSyncSingleLineCommand(channel, "api originate sofia/internal/5562@192.168.23.104 &eavesdrop(" + uuid + ")");
    }
}
