//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   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 de.ugoe.cs.autoquest.plugin.http.eventcore;

import de.ugoe.cs.autoquest.eventcore.IEventType;
import de.ugoe.cs.autoquest.plugin.http.HTTPUtils;
import de.ugoe.cs.autoquest.plugin.http.logdata.HttpExchange;
import de.ugoe.cs.autoquest.plugin.http.logdata.HttpRequest;

/**
 * <p>
 * the event type for HTTP events. Holds a reference to the HTTP exchange recorded by the HTTP
 * monitor.
 * </p>
 * 
 * @author Patrick Harms
 */
public class HTTPEventType implements IEventType {

    /**  */
    private static final long serialVersionUID = 1L;

    /**
     * <p>
     * the HTTP exchange recorded by the HTTP monitor
     * </p>
     */
    private HttpExchange exchange;

    /**
     * <p>
     * the name of the event type as required by AutoQUEST's framework
     * </p>
     */
    private String name;

    /**
     * <p>
     * initializes this event with the represented HTTP exchange
     * </p>
     * 
     * @param exchange the HTTP exchange recorded by the HTTP monitor
     */
    public HTTPEventType(HttpExchange exchange) {
        if (exchange == null) {
            throw new IllegalArgumentException("exchange must not be null");
        }
        
        this.exchange = exchange;
        
        StringBuffer nameBuffer = new StringBuffer("HTTPEvent");
        
        boolean somethingAdded = false;
        
        if ((this.exchange.getRequest() != null) &&
            (this.exchange.getRequest().getMethod() != null))
        {
            nameBuffer.append("(");
            nameBuffer.append(this.exchange.getRequest().getMethod());
            somethingAdded = true;
        }
        
        String senderStr = HTTPUtils.toString(this.exchange.getSender());
        String receiverStr = HTTPUtils.toString(this.exchange.getReceiver());
        
        if ((senderStr != null) && (receiverStr != null)) {
            nameBuffer.append(somethingAdded ? ", " : "(");
            nameBuffer.append(senderStr);
            nameBuffer.append(" --> ");
            nameBuffer.append(receiverStr);
            somethingAdded = true;
        }
        else if (senderStr != null) {
            nameBuffer.append(somethingAdded ? ", " : "(");
            nameBuffer.append(senderStr);
            somethingAdded = true;
        }
        else if (receiverStr != null) {
            nameBuffer.append(somethingAdded ? ", " : "(");
            nameBuffer.append(receiverStr);
            somethingAdded = true;
        }
        
        if (somethingAdded) {
            nameBuffer.append(")");
        }
        
        this.name = nameBuffer.toString();
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.IEventType#getName()
     */
    @Override
    public String getName() {
        return name;
    }

    /**
     * @return the HTTP exchange recorded by the HTTP monitor
     */
    public HttpExchange getExchange() {
        return exchange;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return name;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        
        if (obj instanceof HTTPEventType) {
            HTTPEventType other = (HTTPEventType) obj;
            
            if (!other.getClass().isAssignableFrom(this.getClass())) {
                return false;
            }
            
            if (exchange == null) {
                return other.exchange == null;
            }
            else if (other.exchange == null) {
                return false;
            }
            
            HttpRequest request1 = exchange.getRequest();
            HttpRequest request2 = other.exchange.getRequest();
            
            // do not compare the sender, as this may change
            return (HTTPUtils.equals(exchange.getReceiver(), other.exchange.getReceiver()) &&
                    HTTPUtils.equals(request1.getMethod(), request2.getMethod()) &&
                    HTTPUtils.equals(request1.getProtocol(), request2.getProtocol()) &&
                    HTTPUtils.equals(request1.getUrl(), request2.getUrl()));
        }
        else {
            return false;
        }
    }

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        if (exchange != null) {
            return
                exchange.getRequest().getMethod().hashCode() +
                exchange.getRequest().getProtocol().hashCode() +
                exchange.getRequest().getUrl().hashCode();
        }
        else {
            return 0;
        }
    }

}
