/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.sessions.coordination;

import org.eclipse.persistence.sessions.coordination.ServiceId;

/**
 * <p>
 * <b>Purpose</b>: A structured message object to announce a new RCM service
 * instance becoming available
 * </p><p>
 * <b>Description</b>: This object is sent over the multicast by a service wanting
 * to join the EclipseLink cluster. It is received by all other services subscribing
 * to the same channel. Receipt of this announcement triggers an exchange protocol
 * between the sending and receiving services to establish communications with all
 * of the other services on the channel.
 * </p>
 */
public class ServiceAnnouncement {

    /** The id information of the sending service */
    ServiceId serviceId;

    /**
     * INTERNAL:
     * Constructor to initialize a new instance when receiving a message
     */
    public ServiceAnnouncement(byte[] bytes) {
        readFromBytes(bytes);
    }

    /**
     * INTERNAL:
     * Constructor to initialize a new instance when creating a message
     */
    public ServiceAnnouncement(ServiceId newServiceId) {
        this.serviceId = newServiceId;
    }

    /**
     * INTERNAL:
     * Initialize the instance fields from the serialized bytes.
     *
     * Assumptions:
     *    - Same character converters exist on the reading and storing sides
     *    - Strings are not greater than 255 bytes (bytes, not characters)
     *
     * Byte storage:
     *    - 1 byte to store length of String that is to follow
     *    - String of 'length' bytes follows
     */
    public void readFromBytes(byte[] bytes) {
        serviceId = new ServiceId();
        int curPos = 0;

        // Read the channel
        int channelLength = bytes[curPos];
        curPos++;
        serviceId.setChannel(new String(bytes, curPos, channelLength));
        curPos += channelLength;

        // Read the id
        int idLength = bytes[curPos];
        curPos++;
        serviceId.setId(new String(bytes, curPos, idLength));
        curPos += idLength;

        // Read the URL
        int urlLength = bytes[curPos];
        curPos++;
        if (urlLength > 0) {
            serviceId.setURL(new String(bytes, curPos, urlLength));
        }
    }

    /**
     * INTERNAL:
     * Convert the instance attributes to serialized bytes.
     *
     * Assumptions:
     *    - Same character converters exist on the reading and storing sides
     *    - channel, id and converted to bytes &lt; 256 bytes each
     *
     * Byte storage:
     *    - 1 byte to store length of String that is to follow
     *    - String of 'length' bytes follows
     */
    public byte[] toBytes() {
        byte[] bytes;
        int curPos = 0;

        // Convert the strings to bytes
        byte[] channelBytes = serviceId.getChannel().getBytes();
        int channelLength = channelBytes.length;

        byte[] idBytes = serviceId.getId().getBytes();
        int idLength = idBytes.length;

        byte[] urlBytes = null;
        int urlLength = 0;
        if (serviceId.getURL() == null) {
            urlBytes = new byte[]{};
        } else {
            urlBytes = serviceId.getURL().getBytes();
            urlLength = urlBytes.length;
        }

        // Create the byte array to hold the data
        bytes = new byte[channelLength + idLength + urlLength + 3];

        // Store the fields in the byte array
        bytes[curPos] = (byte)channelLength;
        curPos++;
        System.arraycopy(channelBytes, 0, bytes, curPos, channelLength);
        curPos += channelLength;

        bytes[curPos] = (byte)idLength;
        curPos++;
        System.arraycopy(idBytes, 0, bytes, curPos, idLength);
        curPos += idLength;

        bytes[curPos] = (byte)urlLength;
        curPos++;
        System.arraycopy(urlBytes, 0, bytes, curPos, urlLength);
        return bytes;
    }

    /**
     * INTERNAL:
     * Return the id of the service sending this announcement
     */
    public ServiceId getServiceId() {
        return serviceId;
    }
}
