/*
 * Copyright (C) 2017 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.
 */

#include "io/Util.h"

#include "google/protobuf/io/zero_copy_stream_impl_lite.h"

#include "trace/TraceBuffer.h"

using ::android::StringPiece;
using ::google::protobuf::io::ZeroCopyOutputStream;

namespace aapt {
namespace io {

bool CopyInputStreamToArchive(IAaptContext* context, android::InputStream* in,
                              std::string_view out_path, uint32_t compression_flags,
                              IArchiveWriter* writer) {
  TRACE_CALL();
  if (context->IsVerbose()) {
    context->GetDiagnostics()->Note(android::DiagMessage()
                                    << "writing " << out_path << " to archive");
  }

  if (!writer->WriteFile(out_path, compression_flags, in)) {
    context->GetDiagnostics()->Error(android::DiagMessage()
                                     << "failed to write " << out_path
                                     << " to archive: " << writer->GetError());
    return false;
  }
  return true;
}

bool CopyFileToArchive(IAaptContext* context, io::IFile* file, std::string_view out_path,
                       uint32_t compression_flags, IArchiveWriter* writer) {
  TRACE_CALL();
  std::unique_ptr<io::IData> data = file->OpenAsData();
  if (!data) {
    context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                     << "failed to open file");
    return false;
  }
  return CopyInputStreamToArchive(context, data.get(), out_path, compression_flags, writer);
}

bool CopyFileToArchivePreserveCompression(IAaptContext* context, io::IFile* file,
                                          std::string_view out_path, IArchiveWriter* writer) {
  uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
  return CopyFileToArchive(context, file, out_path, compression_flags, writer);
}

bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::Message* proto_msg,
                        std::string_view out_path, uint32_t compression_flags,
                        IArchiveWriter* writer) {
  TRACE_CALL();
  if (context->IsVerbose()) {
    context->GetDiagnostics()->Note(android::DiagMessage()
                                    << "writing " << out_path << " to archive");
  }

  if (writer->StartEntry(out_path, compression_flags)) {
    // Make sure CopyingOutputStreamAdaptor is deleted before we call writer->FinishEntry().
    {
      // Wrap our IArchiveWriter with an adaptor that implements the ZeroCopyOutputStream interface.
      ::google::protobuf::io::CopyingOutputStreamAdaptor adaptor(writer);
      if (!proto_msg->SerializeToZeroCopyStream(&adaptor)) {
        context->GetDiagnostics()->Error(android::DiagMessage()
                                         << "failed to write " << out_path << " to archive");
        return false;
      }
    }

    if (writer->FinishEntry()) {
      return true;
    }
  }
  context->GetDiagnostics()->Error(android::DiagMessage() << "failed to write " << out_path
                                                          << " to archive: " << writer->GetError());
  return false;
}

bool Copy(android::OutputStream* out, android::InputStream* in) {
  TRACE_CALL();
  const void* in_buffer;
  size_t in_len;
  while (in->Next(&in_buffer, &in_len)) {
    void* out_buffer;
    size_t out_len;
    if (!out->Next(&out_buffer, &out_len)) {
      return !out->HadError();
    }

    const size_t bytes_to_copy = in_len < out_len ? in_len : out_len;
    memcpy(out_buffer, in_buffer, bytes_to_copy);
    out->BackUp(out_len - bytes_to_copy);
    in->BackUp(in_len - bytes_to_copy);
  }
  return !in->HadError();
}

bool Copy(android::OutputStream* out, StringPiece in) {
  const char* in_buffer = in.data();
  size_t in_len = in.size();
  while (in_len != 0) {
    void* out_buffer;
    size_t out_len;
    if (!out->Next(&out_buffer, &out_len)) {
      return false;
    }

    const size_t bytes_to_copy = in_len < out_len ? in_len : out_len;
    memcpy(out_buffer, in_buffer, bytes_to_copy);
    out->BackUp(out_len - bytes_to_copy);
    in_buffer += bytes_to_copy;
    in_len -= bytes_to_copy;
  }
  return true;
}

bool Copy(ZeroCopyOutputStream* out, android::InputStream* in) {
  OutputStreamAdaptor adaptor(out);
  return Copy(&adaptor, in);
}

}  // namespace io
}  // namespace aapt
