// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/printing/ppd_line_reader.h"

#include <memory>
#include <string>
#include <utility>

#include "base/strings/string_util.h"
#include "net/base/io_buffer.h"
#include "net/filter/gzip_header.h"
#include "net/filter/gzip_source_stream.h"
#include "net/filter/source_stream.h"

namespace chromeos {
namespace {

constexpr char kPPDMagicNumberString[] = "*PPD-Adobe:";

// Return true if contents has a valid Gzip header.
bool IsGZipped(const std::string& contents) {
  const char* unused;
  return net::GZipHeader().ReadMore(contents.data(), contents.size(),
                                    &unused) ==
         net::GZipHeader::COMPLETE_HEADER;
}

// Return true if c is a newline in the ppd sense, that is, either newline or
// carriage return.
bool IsNewline(char c) {
  return c == '\n' || c == '\r';
}

// Source stream that reads from a string.  A reference is taken to the string
// used by StringSourceStream; it must not be modified while the
// StringSourceStream exists.
class StringSourceStream : public net::SourceStream {
 public:
  explicit StringSourceStream(const std::string& src)
      : SourceStream(TYPE_UNKNOWN), src_(src) {}

  // This source always reads sychronously, so never uses the callback.
  int Read(net::IOBuffer* dest_buffer,
           int buffer_size,
           const net::CompletionCallback&) override {
    int read_size = src_.size() - read_ofs_;
    if (read_size > buffer_size) {
      read_size = buffer_size;
    }
    memcpy(dest_buffer->data(), src_.data() + read_ofs_, read_size);
    read_ofs_ += read_size;
    return read_size;
  }
  std::string Description() const override { return ""; }

 private:
  int read_ofs_ = 0;
  const std::string& src_;
};

class PpdLineReaderImpl : public PpdLineReader {
 public:
  PpdLineReaderImpl(const std::string& ppd_contents, size_t max_line_length)
      : max_line_length_(max_line_length),
        read_buf_(new net::IOBuffer(kReadBufCapacity)) {
    input_ = std::make_unique<StringSourceStream>(ppd_contents);
    if (IsGZipped(ppd_contents)) {
      input_ = net::GzipSourceStream::Create(std::move(input_),
                                             net::SourceStream::TYPE_GZIP);
    }
  }
  ~PpdLineReaderImpl() override = default;

  bool NextLine(std::string* line) override {
    line->reserve(max_line_length_);

    // Outer loop controls retries; if we fail to read a line, we'll try again
    // after the next newline.
    while (true) {
      line->clear();
      while (line->size() <= max_line_length_) {
        char c = NextChar();
        if (Eof()) {
          return !line->empty();
        } else if (IsNewline(c)) {
          return true;
        }
        line->push_back(c);
      }

      // Exceeded max line length, skip the rest of this line, try for another
      // one.
      if (!SkipToNextLine()) {
        return false;
      }
    }
  }

  bool Error() const override { return error_; }

 private:
  // Chunk size of reads to the underlying source stream.
  static constexpr int kReadBufCapacity = 500;

  // Skip input until we hit a newline (which is discarded).  If
  // we encounter eof before a newline, false is returned.
  bool SkipToNextLine() {
    while (true) {
      char c = NextChar();
      if (Eof()) {
        return false;
      }
      if (IsNewline(c)) {
        return true;
      }
    }
  }

  // Consume and return the next char from the source stream.  If there is no
  // more data to be had, set eof.  Eof() should be checked before the returned
  // value is used.
  char NextChar() {
    if (read_ofs_ == read_buf_size_) {
      // Grab more data from the underlying stream.
      read_ofs_ = 0;

      // Since StringSourceStream never uses the callback, and filter streams
      // are only supposed to use the callback if the underlying source stream
      // uses it, we should never see the callback used.
      int result = input_->Read(
          read_buf_.get(), kReadBufCapacity,
          base::Bind([](int) { LOG(FATAL) << "Unexpected async read"; }));
      if (result == 0) {
        eof_ = true;
        return '\0';
      } else if (result < 0) {
        eof_ = true;
        error_ = true;
      }
      read_buf_size_ = result;
    }
    return read_buf_->data()[read_ofs_++];
  }

  bool Eof() const { return eof_; }

  // Maximum allowable line length from the source.  Any lines longer than this
  // will be silently discarded.
  size_t max_line_length_;

  // Buffer for reading from the source stream.
  scoped_refptr<net::IOBuffer> read_buf_;
  // Number of bytes actually in the buffer.
  int read_buf_size_ = 0;
  // Offset into read_buf for the next char.
  int read_ofs_ = 0;

  // Have we hit the end of the source stream?
  bool eof_ = false;

  // Did we encounter an error while reading?
  bool error_ = false;

  // The input stream we're reading bytes from.  This may be a gzip source
  // stream or string source stream depending on the source data.
  std::unique_ptr<net::SourceStream> input_;
};

}  // namespace

// static
std::unique_ptr<PpdLineReader> PpdLineReader::Create(
    const std::string& contents,
    int max_line_length) {
  return std::make_unique<PpdLineReaderImpl>(contents, max_line_length);
}

// static
bool PpdLineReader::ContainsMagicNumber(const std::string& contents,
                                        int max_line_length) {
  auto line_reader = PpdLineReader::Create(contents, max_line_length);
  std::string line;
  return line_reader->NextLine(&line) &&
         base::StartsWith(line, kPPDMagicNumberString,
                          base::CompareCase::SENSITIVE);
}

}  // namespace chromeos
