//===- DXContainerObjcopy.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ObjCopy/DXContainer/DXContainerObjcopy.h"
#include "DXContainerReader.h"
#include "DXContainerWriter.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/ObjCopy/CommonConfig.h"
#include "llvm/ObjCopy/DXContainer/DXContainerConfig.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/raw_ostream.h"

namespace llvm {
namespace objcopy {
namespace dxbc {

using namespace object;

static Error extractPartAsObject(StringRef PartName, StringRef OutFilename,
                                 StringRef InputFilename, const Object &Obj) {
  auto *PartIter = llvm::find_if(
      Obj.Parts, [&PartName](const Part &P) { return P.Name == PartName; });
  if (PartIter == Obj.Parts.end())
    return createFileError(InputFilename,
                           std::make_error_code(std::errc::invalid_argument),
                           "part '%s' not found", PartName.str().c_str());

  Object PartObj;
  PartObj.Header = Obj.Header;
  PartObj.Parts.push_back({PartIter->Name, PartIter->Data});
  PartObj.recomputeHeader();

  auto Write = [&OutFilename, &PartObj](raw_ostream &Out) -> Error {
    DXContainerWriter Writer(PartObj, Out);
    if (Error E = Writer.write())
      return createFileError(OutFilename, std::move(E));
    return Error::success();
  };

  return writeToOutput(OutFilename, Write);
}

static Error dumpPartToFile(StringRef PartName, StringRef Filename,
                            StringRef InputFilename, Object &Obj) {
  auto *PartIter = llvm::find_if(
      Obj.Parts, [&PartName](const Part &P) { return P.Name == PartName; });
  if (PartIter == Obj.Parts.end())
    return createFileError(Filename,
                           std::make_error_code(std::errc::invalid_argument),
                           "part '%s' not found", PartName.str().c_str());

  ArrayRef<uint8_t> Contents = PartIter->Data;
  // The DXContainer format is a bit odd because the part-specific headers are
  // contained inside the part data itself. For parts that contain LLVM bitcode
  // when we dump the part we want to skip the part-specific header so that we
  // get a valid .bc file that we can inspect. All the data contained inside the
  // program header is pulled out of the bitcode, so the header can be
  // reconstructed if needed from the bitcode itself. More comprehensive
  // documentation on the DXContainer format can be found at
  // https://llvm.org/docs/DirectX/DXContainer.html.

  if (llvm::dxbc::isProgramPart(PartName) || PartName == "STAT")
    Contents = Contents.drop_front(sizeof(llvm::dxbc::ProgramHeader));
  if (Contents.empty())
    return createFileError(Filename, object_error::parse_failed,
                           "part '%s' is empty", PartName.str().c_str());
  Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
      FileOutputBuffer::create(Filename, Contents.size());
  if (!BufferOrErr)
    return createFileError(Filename, BufferOrErr.takeError());
  std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
  llvm::copy(Contents, Buf->getBufferStart());
  if (Error E = Buf->commit())
    return createFileError(Filename, std::move(E));
  return Error::success();
}

static Error handleArgs(const CommonConfig &Config, Object &Obj) {
  for (StringRef Flag : Config.DumpSection) {
    auto [SectionName, FileName] = Flag.split("=");
    if (Error E =
            dumpPartToFile(SectionName, FileName, Config.InputFilename, Obj))
      return E;
  }

  // Extract all sections before any modifications.
  for (StringRef Flag : Config.ExtractSection) {
    auto [SectionName, FileName] = Flag.split('=');
    if (Error E = extractPartAsObject(SectionName, FileName,
                                      Config.InputFilename, Obj))
      return E;
  }

  std::function<bool(const Part &)> RemovePred = [](const Part &) {
    return false;
  };

  if (!Config.ToRemove.empty())
    RemovePred = [&Config](const Part &P) {
      return Config.ToRemove.matches(P.Name);
    };

  if (!Config.OnlySection.empty())
    RemovePred = [&Config](const Part &P) {
      // Explicitly keep these sections regardless of previous removes and
      // remove everything else.
      return !Config.OnlySection.matches(P.Name);
    };

  if (auto E = Obj.removeParts(RemovePred))
    return E;

  Obj.recomputeHeader();
  return Error::success();
}

Error executeObjcopyOnBinary(const CommonConfig &Config,
                             const DXContainerConfig &,
                             DXContainerObjectFile &In, raw_ostream &Out) {
  DXContainerReader Reader(In);
  Expected<std::unique_ptr<Object>> ObjOrErr = Reader.create();
  if (!ObjOrErr)
    return createFileError(Config.InputFilename, ObjOrErr.takeError());
  Object *Obj = ObjOrErr->get();
  assert(Obj && "Unable to deserialize DXContainer object");

  if (Error E = handleArgs(Config, *Obj))
    return E;

  DXContainerWriter Writer(*Obj, Out);
  if (Error E = Writer.write())
    return createFileError(Config.OutputFilename, std::move(E));
  return Error::success();
}

} // end namespace dxbc
} // end namespace objcopy
} // end namespace llvm
