/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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.
 */

#pragma once

#include <stdint.h>

#include <android-base/macros.h>

#include "adb.h"
#include "adb_unique_fd.h"

// Class to send and receive shell protocol packets.
//
// To keep things simple and predictable, reads and writes block until an entire
// packet is complete.
//
// Example: read raw data from |fd| and send it in a packet.
//   ShellProtocol* p = new ShellProtocol(protocol_fd);
//   int len = adb_read(stdout_fd, p->data(), p->data_capacity());
//   packet->WritePacket(ShellProtocol::kIdStdout, len);
//
// Example: read a packet and print it to |stdout|.
//   ShellProtocol* p = new ShellProtocol(protocol_fd);
//   if (p->ReadPacket() && p->id() == kIdStdout) {
//       fwrite(p->data(), 1, p->data_length(), stdout);
//   }
class ShellProtocol {
  public:
    // This is an unscoped enum to make it easier to compare against raw bytes.
    enum Id : uint8_t {
        kIdStdin = 0,
        kIdStdout = 1,
        kIdStderr = 2,
        kIdExit = 3,

        // Close subprocess stdin if possible.
        kIdCloseStdin = 4,

        // Window size change (an ASCII version of struct winsize).
        kIdWindowSizeChange = 5,

        // Indicates an invalid or unknown packet.
        kIdInvalid = 255,
    };

    // ShellPackets will probably be too large to allocate on the stack so they
    // should be dynamically allocated on the heap instead.
    //
    // |fd| is an open file descriptor to be used to send or receive packets.
    explicit ShellProtocol(borrowed_fd fd);
    virtual ~ShellProtocol();

    // Returns a pointer to the data buffer.
    const char* data() const { return buffer_ + kHeaderSize; }
    char* data() { return buffer_ + kHeaderSize; }

    // Returns the total capacity of the data buffer.
    size_t data_capacity() const { return buffer_end_ - data(); }

    // Reads a packet from the FD.
    //
    // If a packet is too big to fit in the buffer then Read() will split the
    // packet across multiple calls. For example, reading a 50-byte packet into
    // a 20-byte buffer would read 20 bytes, 20 bytes, then 10 bytes.
    //
    // Returns false if the FD closed or errored.
    bool Read();

    // Returns the ID of the packet in the buffer.
    int id() const { return buffer_[0]; }

    // Returns the number of bytes that have been read into the data buffer.
    size_t data_length() const { return data_length_; }

    // Writes the packet currently in the buffer to the FD.
    //
    // Returns false if the FD closed or errored.
    bool Write(Id id, size_t length);

  private:
    // Packets support 4-byte lengths.
    typedef uint32_t length_t;

    enum {
        // It's OK if MAX_PAYLOAD doesn't match on the sending and receiving
        // end, reading will split larger packets into multiple smaller ones.
        kBufferSize = MAX_PAYLOAD,

        // Header is 1 byte ID + 4 bytes length.
        kHeaderSize = sizeof(Id) + sizeof(length_t)
    };

    borrowed_fd fd_;
    char buffer_[kBufferSize];
    size_t data_length_ = 0, bytes_left_ = 0;

    // We need to be able to modify this value for testing purposes, but it
    // will stay constant during actual program use.
    char* buffer_end_ = buffer_ + sizeof(buffer_);

    friend class ShellProtocolTest;

    DISALLOW_COPY_AND_ASSIGN(ShellProtocol);
};
