/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */

package com.sleepycat.je.rep.impl.networkRestore;

import java.nio.ByteBuffer;

import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.log.LogUtils;
import com.sleepycat.je.rep.impl.node.NameIdPair;
import com.sleepycat.je.rep.utilint.BinaryProtocol;
import com.sleepycat.je.utilint.VLSN;

/**
 * The protocol used to obtain backup files from a LF Feeder. The message
 * exchange is always initiated by the client.
 *
 * The following describes the request/response messages exchanged between the
 * two nodes:
 *
 * {@literal
 *      FeederInfoReq -> FeederInfoResp
 *
 *      FileListReq -> FileListResp
 *
 *      FileInfoReq -> FileInfoResp
 *
 *      FileReq -> FileStart <byte stream> FileEnd
 *
 *      Done
 * }
 *
 * So a complete sequence of successful request messages looks like:
 *
 * FeederInfoReq FileListReq [[FileInfoReq] [FileReq] ]+ Done
 *
 * A response sequence would look like:
 *
 * FeederInfoResp FileListResp [[FileInfoResp] [FileStart <i>byte stream</i> FileEnd] ]+
 *
 * The client may abandon its interaction with the server if it decides the
 * server is overloaded.
 *
 * The client tries to minimize the number of files it actually requests based
 * upon its current state.
 *
 * When a FileReq is received by the server, other files previously requested
 * (using FileReq) may be deleted by the server. These previously requested
 * files must not be requested again using FileReq or FileReqInfo.
 */
public class Protocol extends BinaryProtocol {

    static public final int VERSION = 2;

    /* The messages defined by this class. */
    public final MessageOp FEEDER_INFO_REQ =
        new MessageOp((short)1, FeederInfoReq.class);

    public final MessageOp FEEDER_INFO_RESP =
        new MessageOp((short)2, FeederInfoResp.class);

    public final MessageOp FILE_LIST_REQ =
        new MessageOp((short)3, FileListReq.class);

    public final MessageOp FILE_LIST_RESP =
        new MessageOp((short)4, FileListResp.class);

    public final MessageOp FILE_REQ =
        new MessageOp((short)5, FileReq.class);

    public final MessageOp FILE_START =
        new MessageOp((short)6, FileStart.class);

    public final MessageOp FILE_END =
        new MessageOp((short)7, FileEnd.class);

    public final MessageOp FILE_INFO_REQ =
        new MessageOp((short)8, FileInfoReq.class);

    public final MessageOp FILE_INFO_RESP =
        new MessageOp((short)9, FileInfoResp.class);

    public final MessageOp DONE =
        new MessageOp((short)10, Done.class);

    public Protocol(NameIdPair nameIdPair,
                    int configuredVersion,
                    EnvironmentImpl envImpl) {

        super(nameIdPair, VERSION, configuredVersion, envImpl);

        initializeMessageOps(new MessageOp[]
                             {FEEDER_INFO_REQ,
                              FEEDER_INFO_RESP,
                              FILE_LIST_REQ,
                              FILE_LIST_RESP,
                              FILE_INFO_REQ,
                              FILE_INFO_RESP,
                              FILE_REQ,
                              FILE_START,
                              FILE_END,
                              DONE});
    }

    /* Requests the list of log files that need to be backed up. */
    public class FeederInfoReq extends SimpleMessage {

        public FeederInfoReq() {
            super();
        }

        @SuppressWarnings("unused")
        public FeederInfoReq(ByteBuffer buffer) {
            super();
        }

        @Override
        public MessageOp getOp() {
            return FEEDER_INFO_REQ;
        }
    }

    public class FeederInfoResp extends SimpleMessage {
        /* The number of feeders that are currently busy at this server. */
        private final int activeFeeders;

        /* The vlsn range covered by this server if it's a rep node. */
        private final VLSN rangeFirst;
        private final VLSN rangeLast;

        public FeederInfoResp(int activeFeeders,
                              VLSN rangeFirst,
                              VLSN rangeLast) {
            super();
            this.activeFeeders = activeFeeders;
            this.rangeFirst = rangeFirst;
            this.rangeLast = rangeLast;
        }

        public FeederInfoResp(ByteBuffer buffer) {
            super();
            activeFeeders = LogUtils.readInt(buffer);
            rangeFirst = getVLSN(buffer);
            rangeLast = getVLSN(buffer);
        }

        @Override
        public MessageOp getOp() {
            return FEEDER_INFO_RESP;
        }

        @Override
        public ByteBuffer wireFormat() {
            return wireFormat(activeFeeders, rangeFirst, rangeLast);
        }

        public int getActiveFeeders() {
            return activeFeeders;
        }

        public VLSN getRangeFirst() {
            return rangeFirst;
        }

        public VLSN getRangeLast() {
            return rangeLast;
        }
    }

    /* Requests the list of log files that need to be backed up. */
    public class FileListReq extends SimpleMessage {

        public FileListReq() {
            super();
        }

        @SuppressWarnings("unused")
        public FileListReq(ByteBuffer buffer) {
            super();
        }

        @Override
        public MessageOp getOp() {
            return FILE_LIST_REQ;
        }
    }

    /* Response to the above containing the list of files. */
    public class FileListResp extends SimpleMessage {
        private final String[] fileNames;

        public FileListResp(String[] fileNames) {
            super();
            this.fileNames = fileNames;
        }

        public FileListResp(ByteBuffer buffer) {
            fileNames = getStringArray(buffer);
        }

        @Override
        public MessageOp getOp() {
            return FILE_LIST_RESP;
        }

        @Override
        public ByteBuffer wireFormat() {
            return wireFormat((Object)fileNames);
        }

        public String[] getFileNames() {
            return fileNames;
        }
    }

    /**
     * Requests that a specific file be sent to the client.
     */
    public class FileReq extends SimpleMessage {

        protected final String fileName;

        public FileReq(String fileName) {
            super();
            this.fileName = fileName;
        }

        public FileReq(ByteBuffer buffer) {
            fileName = getString(buffer);
        }

        @Override
        public MessageOp getOp() {
            return FILE_REQ;
        }

        @Override
        public ByteBuffer wireFormat() {
            return wireFormat(fileName);
        }

        public String getFileName() {
            return fileName;
        }
    }

    /**
     * Requests information about a specific log file.
     */
    public class FileInfoReq extends FileReq {
        private final boolean needSHA1;

        public FileInfoReq(String fileName, boolean needSHA1) {
            super(fileName);
            this.needSHA1 = needSHA1;
        }

        public FileInfoReq(ByteBuffer buffer) {
            super(buffer);
            needSHA1 = getBoolean(buffer);
        }

        @Override
        public MessageOp getOp() {
            return FILE_INFO_REQ;
        }

        @Override
        public ByteBuffer wireFormat() {
            return super.wireFormat(fileName, needSHA1);
        }

        public boolean getNeedSHA1() {
            return needSHA1;
        }
    }

    /*
     * The Response for information about a specific log file.
     */
    public class FileInfoResp extends FileStart {
        private final byte[] digestSHA1;

        public FileInfoResp(String fileName,
                            long fileLength,
                            long lastModifiedTime,
                            byte[] digestSHA1) {
            super(fileName, fileLength, lastModifiedTime);
            this.digestSHA1 = digestSHA1;
        }

        public FileInfoResp(ByteBuffer buffer) {
            super(buffer);
            this.digestSHA1 = getByteArray(buffer);
        }

        @Override
        public MessageOp getOp() {
            return FILE_INFO_RESP;
        }

        @Override
        public ByteBuffer wireFormat() {
            return wireFormat(fileName,
                              fileLength,
                              lastModifiedTime,
                              digestSHA1);
        }

        /**
         * Returns the SHA1 value if it was requested, or a zero length byte
         * array if it was not requested.
         */
        public byte[] getDigestSHA1() {
            return digestSHA1;
        }
    }

    /**
     * The message starting the response triple:
     *
     * FileStart <i>byte stream</i> FileEnd
     */
    public class FileStart extends SimpleMessage {
        /* Must match the request name. */
        protected final String fileName;

        /* The actual file length in bytes on disk */
        protected final long fileLength;
        protected final long lastModifiedTime;

        public FileStart(String fileName,
                         long fileLength,
                         long lastModifiedTime) {
            super();
            this.fileName = fileName;
            this.fileLength = fileLength;
            this.lastModifiedTime = lastModifiedTime;
        }

        public FileStart(ByteBuffer buffer) {
            fileName = getString(buffer);
            fileLength = LogUtils.readLong(buffer);
            lastModifiedTime = LogUtils.readLong(buffer);
        }

        @Override
        public MessageOp getOp() {
            return FILE_START;
        }

        @Override
        public ByteBuffer wireFormat() {
            return wireFormat(fileName, fileLength, lastModifiedTime);
        }

        public long getFileLength() {
            return fileLength;
        }

        public long getLastModifiedTime() {
            return lastModifiedTime;
        }
    }

    /**
     * The message ending the response triple:
     *
     * FileStart <i>byte stream</i> FileEnd
     */
    public class FileEnd extends FileInfoResp {

        public FileEnd(String fileName,
                       long fileLength,
                       long lastModifiedTime,
                       byte[] digestSHA1) {
            super(fileName, fileLength, lastModifiedTime, digestSHA1);
        }

        public FileEnd(ByteBuffer buffer) {
            super(buffer);
        }

        @Override
        public MessageOp getOp() {
            return FILE_END;
        }

        @Override
        public ByteBuffer wireFormat() {
            return super.wireFormat();
        }
    }

    /**
     * Message from client indicating it's done with all the files it needs and
     * that the connection can be terminated.
     */
    public class Done extends SimpleMessage {

        public Done() {
            super();
        }

        @SuppressWarnings("unused")
        public Done(ByteBuffer buffer) {
            super();
        }

        @Override
        public MessageOp getOp() {
            return DONE;
        }
    }
}
