//
//  ========================================================================
//  Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.http2.frames;

import java.util.Objects;

public class PingFrame extends Frame
{
    public static final int PING_LENGTH = 8;
    private static final byte[] EMPTY_PAYLOAD = new byte[8];

    private final byte[] payload;
    private final boolean reply;

    /**
     * Creates a PING frame with an empty payload.
     *
     * @param reply whether this PING frame is a reply
     */
    public PingFrame(boolean reply)
    {
        this(EMPTY_PAYLOAD, reply);
    }

    /**
     * Creates a PING frame with the given {@code long} {@code value} as payload.
     *
     * @param value the value to use as a payload for this PING frame
     * @param reply whether this PING frame is a reply
     */
    public PingFrame(long value, boolean reply)
    {
        this(toBytes(value), reply);
    }

    /**
     * Creates a PING frame with the given {@code payload}.
     *
     * @param payload the payload for this PING frame
     * @param reply whether this PING frame is a reply
     */
    public PingFrame(byte[] payload, boolean reply)
    {
        super(FrameType.PING);
        this.payload = Objects.requireNonNull(payload);
        if (payload.length != PING_LENGTH)
            throw new IllegalArgumentException("PING payload must be 8 bytes");
        this.reply = reply;
    }

    public byte[] getPayload()
    {
        return payload;
    }

    public long getPayloadAsLong()
    {
        return toLong(payload);
    }

    public boolean isReply()
    {
        return reply;
    }

    private static byte[] toBytes(long value)
    {
        byte[] result = new byte[8];
        for (int i = result.length - 1; i >= 0; --i)
        {
            result[i] = (byte)(value & 0xFF);
            value >>= 8;
        }
        return result;
    }

    private static long toLong(byte[] payload)
    {
        long result = 0;
        for (int i = 0; i < 8; ++i)
        {
            result <<= 8;
            result |= (payload[i] & 0xFF);
        }
        return result;
    }
}
