//===-- WindowsResource.h ---------------------------------------*- C++-*-===//
//
// 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
//
//===---------------------------------------------------------------------===//
//
// This file declares the .res file class.  .res files are intermediate
// products of the typical resource-compilation process on Windows.  This
// process is as follows:
//
// .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file
//
// .rc files are human-readable scripts that list all resources a program uses.
//
// They are compiled into .res files, which are a list of the resources in
// binary form.
//
// Finally the data stored in the .res is compiled into a COFF file, where it
// is organized in a directory tree structure for optimized access by the
// program during runtime.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx
//
//===---------------------------------------------------------------------===//

#ifndef LLVM_OBJECT_WINDOWSRESOURCE_H
#define LLVM_OBJECT_WINDOWSRESOURCE_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"

#include <map>

namespace llvm {

class raw_ostream;
class ScopedPrinter;

namespace object {

class WindowsResource;
class ResourceSectionRef;
struct coff_resource_dir_table;

const size_t WIN_RES_MAGIC_SIZE = 16;
const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;

struct WinResHeaderPrefix {
  support::ulittle32_t DataSize;
  support::ulittle32_t HeaderSize;
};

// Type and Name may each either be an integer ID or a string.  This struct is
// only used in the case where they are both IDs.
struct WinResIDs {
  uint16_t TypeFlag;
  support::ulittle16_t TypeID;
  uint16_t NameFlag;
  support::ulittle16_t NameID;

  void setType(uint16_t ID) {
    TypeFlag = 0xffff;
    TypeID = ID;
  }

  void setName(uint16_t ID) {
    NameFlag = 0xffff;
    NameID = ID;
  }
};

struct WinResHeaderSuffix {
  support::ulittle32_t DataVersion;
  support::ulittle16_t MemoryFlags;
  support::ulittle16_t Language;
  support::ulittle32_t Version;
  support::ulittle32_t Characteristics;
};

class EmptyResError : public GenericBinaryError {
public:
  EmptyResError(Twine Msg, object_error ECOverride)
      : GenericBinaryError(Msg, ECOverride) {}
};

class ResourceEntryRef {
public:
  Error moveNext(bool &End);
  bool checkTypeString() const { return IsStringType; }
  ArrayRef<UTF16> getTypeString() const { return Type; }
  uint16_t getTypeID() const { return TypeID; }
  bool checkNameString() const { return IsStringName; }
  ArrayRef<UTF16> getNameString() const { return Name; }
  uint16_t getNameID() const { return NameID; }
  uint16_t getDataVersion() const { return Suffix->DataVersion; }
  uint16_t getLanguage() const { return Suffix->Language; }
  uint16_t getMemoryFlags() const { return Suffix->MemoryFlags; }
  uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
  uint16_t getMinorVersion() const { return Suffix->Version; }
  uint32_t getCharacteristics() const { return Suffix->Characteristics; }
  ArrayRef<uint8_t> getData() const { return Data; }

private:
  friend class WindowsResource;

  ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner);
  Error loadNext();

  static Expected<ResourceEntryRef> create(BinaryStreamRef Ref,
                                           const WindowsResource *Owner);

  BinaryStreamReader Reader;
  const WindowsResource *Owner;
  bool IsStringType;
  ArrayRef<UTF16> Type;
  uint16_t TypeID;
  bool IsStringName;
  ArrayRef<UTF16> Name;
  uint16_t NameID;
  const WinResHeaderSuffix *Suffix = nullptr;
  ArrayRef<uint8_t> Data;
};

class WindowsResource : public Binary {
public:
  Expected<ResourceEntryRef> getHeadEntry();

  static bool classof(const Binary *V) { return V->isWinRes(); }

  static Expected<std::unique_ptr<WindowsResource>>
  createWindowsResource(MemoryBufferRef Source);

private:
  friend class ResourceEntryRef;

  WindowsResource(MemoryBufferRef Source);

  BinaryByteStream BBS;
};

class WindowsResourceParser {
public:
  class TreeNode;
  WindowsResourceParser(bool MinGW = false);
  Error parse(WindowsResource *WR, std::vector<std::string> &Duplicates);
  Error parse(ResourceSectionRef &RSR, StringRef Filename,
              std::vector<std::string> &Duplicates);
  void cleanUpManifests(std::vector<std::string> &Duplicates);
  void printTree(raw_ostream &OS) const;
  const TreeNode &getTree() const { return Root; }
  ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
  ArrayRef<std::vector<UTF16>> getStringTable() const { return StringTable; }

  class TreeNode {
  public:
    template <typename T>
    using Children = std::map<T, std::unique_ptr<TreeNode>>;

    void print(ScopedPrinter &Writer, StringRef Name) const;
    uint32_t getTreeSize() const;
    uint32_t getStringIndex() const { return StringIndex; }
    uint32_t getDataIndex() const { return DataIndex; }
    uint16_t getMajorVersion() const { return MajorVersion; }
    uint16_t getMinorVersion() const { return MinorVersion; }
    uint32_t getCharacteristics() const { return Characteristics; }
    bool checkIsDataNode() const { return IsDataNode; }
    const Children<uint32_t> &getIDChildren() const { return IDChildren; }
    const Children<std::string> &getStringChildren() const {
      return StringChildren;
    }

  private:
    friend class WindowsResourceParser;

    // Index is the StringTable vector index for this node's name.
    static std::unique_ptr<TreeNode> createStringNode(uint32_t Index);
    static std::unique_ptr<TreeNode> createIDNode();
    // DataIndex is the Data vector index that the data node points at.
    static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
                                                    uint16_t MinorVersion,
                                                    uint32_t Characteristics,
                                                    uint32_t Origin,
                                                    uint32_t DataIndex);

    explicit TreeNode(uint32_t StringIndex);
    TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
             uint32_t Characteristics, uint32_t Origin, uint32_t DataIndex);

    bool addEntry(const ResourceEntryRef &Entry, uint32_t Origin,
                  std::vector<std::vector<uint8_t>> &Data,
                  std::vector<std::vector<UTF16>> &StringTable,
                  TreeNode *&Result);
    TreeNode &addTypeNode(const ResourceEntryRef &Entry,
                          std::vector<std::vector<UTF16>> &StringTable);
    TreeNode &addNameNode(const ResourceEntryRef &Entry,
                          std::vector<std::vector<UTF16>> &StringTable);
    bool addLanguageNode(const ResourceEntryRef &Entry, uint32_t Origin,
                         std::vector<std::vector<uint8_t>> &Data,
                         TreeNode *&Result);
    bool addDataChild(uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
                      uint32_t Characteristics, uint32_t Origin,
                      uint32_t DataIndex, TreeNode *&Result);
    TreeNode &addIDChild(uint32_t ID);
    TreeNode &addNameChild(ArrayRef<UTF16> NameRef,
                           std::vector<std::vector<UTF16>> &StringTable);
    void shiftDataIndexDown(uint32_t Index);

    bool IsDataNode = false;
    uint32_t StringIndex;
    uint32_t DataIndex;
    Children<uint32_t> IDChildren;
    Children<std::string> StringChildren;
    uint16_t MajorVersion = 0;
    uint16_t MinorVersion = 0;
    uint32_t Characteristics = 0;

    // The .res file that defined this TreeNode, for diagnostics.
    // Index into InputFilenames.
    uint32_t Origin;
  };

  struct StringOrID {
    bool IsString;
    ArrayRef<UTF16> String;
    uint32_t ID;

    StringOrID(uint32_t ID) : IsString(false), ID(ID) {}
    StringOrID(ArrayRef<UTF16> String) : IsString(true), String(String) {}
  };

private:
  Error addChildren(TreeNode &Node, ResourceSectionRef &RSR,
                    const coff_resource_dir_table &Table, uint32_t Origin,
                    std::vector<StringOrID> &Context,
                    std::vector<std::string> &Duplicates);
  bool shouldIgnoreDuplicate(const ResourceEntryRef &Entry) const;
  bool shouldIgnoreDuplicate(const std::vector<StringOrID> &Context) const;

  TreeNode Root;
  std::vector<std::vector<uint8_t>> Data;
  std::vector<std::vector<UTF16>> StringTable;

  std::vector<std::string> InputFilenames;

  bool MinGW;
};

Expected<std::unique_ptr<MemoryBuffer>>
writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
                         const WindowsResourceParser &Parser,
                         uint32_t TimeDateStamp);

void printResourceTypeName(uint16_t TypeID, raw_ostream &OS);
} // namespace object
} // namespace llvm

#endif
