//===-- ResourceSerializator.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 defines a visitor serializing resources to a .res stream.
//
//===---------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_LLVMRC_RESOURCESERIALIZATOR_H
#define LLVM_TOOLS_LLVMRC_RESOURCESERIALIZATOR_H

#include "ResourceScriptStmt.h"
#include "ResourceVisitor.h"

#include "llvm/Support/Endian.h"

namespace llvm {

class MemoryBuffer;

namespace rc {

enum CodePage {
  CpAcp = 0,        // The current used codepage. Since there's no such
                    // notion in LLVM what codepage it actually means,
                    // this only allows ASCII.
  CpWin1252 = 1252, // A codepage where most 8 bit values correspond to
                    // unicode code points with the same value.
  CpUtf8 = 65001,   // UTF-8.
};

struct WriterParams {
  std::vector<std::string> Include;   // Additional folders to search for files.
  bool NoInclude;                     // Ignore the INCLUDE variable.
  StringRef InputFilePath;            // The full path of the input file.
  int CodePage = CpAcp;               // The codepage for interpreting characters.
};

class ResourceFileWriter : public Visitor {
public:
  ResourceFileWriter(const WriterParams &Params,
                     std::unique_ptr<raw_fd_ostream> Stream)
      : Params(Params), FS(std::move(Stream)), IconCursorID(1) {
    assert(FS && "Output stream needs to be provided to the serializator");
  }

  Error visitNullResource(const RCResource *) override;
  Error visitAcceleratorsResource(const RCResource *) override;
  Error visitCursorResource(const RCResource *) override;
  Error visitDialogResource(const RCResource *) override;
  Error visitHTMLResource(const RCResource *) override;
  Error visitIconResource(const RCResource *) override;
  Error visitMenuResource(const RCResource *) override;
  Error visitVersionInfoResource(const RCResource *) override;
  Error visitStringTableResource(const RCResource *) override;
  Error visitUserDefinedResource(const RCResource *) override;

  Error visitCaptionStmt(const CaptionStmt *) override;
  Error visitCharacteristicsStmt(const CharacteristicsStmt *) override;
  Error visitClassStmt(const ClassStmt *) override;
  Error visitExStyleStmt(const ExStyleStmt *) override;
  Error visitFontStmt(const FontStmt *) override;
  Error visitLanguageStmt(const LanguageResource *) override;
  Error visitStyleStmt(const StyleStmt *) override;
  Error visitVersionStmt(const VersionStmt *) override;

  // Stringtables are output at the end of .res file. We need a separate
  // function to do it.
  Error dumpAllStringTables();

  bool AppendNull = false; // Append '\0' to each existing STRINGTABLE element?

  struct ObjectInfo {
    uint16_t LanguageInfo;
    uint32_t Characteristics;
    uint32_t VersionInfo;

    Optional<uint32_t> Style;
    Optional<uint32_t> ExStyle;
    StringRef Caption;
    struct FontInfo {
      uint32_t Size;
      StringRef Typeface;
      uint32_t Weight;
      bool IsItalic;
      uint32_t Charset;
    };
    Optional<FontInfo> Font;
    IntOrString Class;

    ObjectInfo()
        : LanguageInfo(0), Characteristics(0), VersionInfo(0),
          Class(StringRef()) {}
  } ObjectData;

  struct StringTableInfo {
    // Each STRINGTABLE bundle depends on ID of the bundle and language
    // description.
    using BundleKey = std::pair<uint16_t, uint16_t>;
    // Each bundle is in fact an array of 16 strings.
    struct Bundle {
      std::array<Optional<std::vector<StringRef>>, 16> Data;
      ObjectInfo DeclTimeInfo;
      uint16_t MemoryFlags;
      Bundle(const ObjectInfo &Info, uint16_t Flags)
          : DeclTimeInfo(Info), MemoryFlags(Flags) {}
    };
    std::map<BundleKey, Bundle> BundleData;
    // Bundles are listed in the order of their first occurrence.
    std::vector<BundleKey> BundleList;
  } StringTableData;

private:
  Error handleError(Error Err, const RCResource *Res);

  Error
  writeResource(const RCResource *Res,
                Error (ResourceFileWriter::*BodyWriter)(const RCResource *));

  // NullResource
  Error writeNullBody(const RCResource *);

  // AcceleratorsResource
  Error writeSingleAccelerator(const AcceleratorsResource::Accelerator &,
                               bool IsLastItem);
  Error writeAcceleratorsBody(const RCResource *);

  // BitmapResource
  Error visitBitmapResource(const RCResource *) override;
  Error writeBitmapBody(const RCResource *);

  // CursorResource and IconResource
  Error visitIconOrCursorResource(const RCResource *);
  Error visitIconOrCursorGroup(const RCResource *);
  Error visitSingleIconOrCursor(const RCResource *);
  Error writeSingleIconOrCursorBody(const RCResource *);
  Error writeIconOrCursorGroupBody(const RCResource *);

  // DialogResource
  Error writeSingleDialogControl(const Control &, bool IsExtended);
  Error writeDialogBody(const RCResource *);

  // HTMLResource
  Error writeHTMLBody(const RCResource *);

  // MenuResource
  Error writeMenuDefinition(const std::unique_ptr<MenuDefinition> &,
                            uint16_t Flags);
  Error writeMenuDefinitionList(const MenuDefinitionList &List);
  Error writeMenuBody(const RCResource *);

  // StringTableResource
  Error visitStringTableBundle(const RCResource *);
  Error writeStringTableBundleBody(const RCResource *);
  Error insertStringIntoBundle(StringTableInfo::Bundle &Bundle,
                               uint16_t StringID,
                               const std::vector<StringRef> &String);

  // User defined resource
  Error writeUserDefinedBody(const RCResource *);

  // VersionInfoResource
  Error writeVersionInfoBody(const RCResource *);
  Error writeVersionInfoBlock(const VersionInfoBlock &);
  Error writeVersionInfoValue(const VersionInfoValue &);

  const WriterParams &Params;

  // Output stream handling.
  std::unique_ptr<raw_fd_ostream> FS;

  uint64_t tell() const { return FS->tell(); }

  uint64_t writeObject(const ArrayRef<uint8_t> Data);

  template <typename T> uint64_t writeInt(const T &Value) {
    support::detail::packed_endian_specific_integral<T, support::little,
                                                     support::unaligned>
        Object(Value);
    return writeObject(Object);
  }

  template <typename T> uint64_t writeObject(const T &Value) {
    return writeObject(ArrayRef<uint8_t>(
        reinterpret_cast<const uint8_t *>(&Value), sizeof(T)));
  }

  template <typename T> void writeObjectAt(const T &Value, uint64_t Position) {
    FS->pwrite((const char *)&Value, sizeof(T), Position);
  }

  Error writeCString(StringRef Str, bool WriteTerminator = true);

  Error writeIdentifier(const IntOrString &Ident);
  Error writeIntOrString(const IntOrString &Data);

  void writeRCInt(RCInt);

  Error appendFile(StringRef Filename);

  void padStream(uint64_t Length);

  Expected<std::unique_ptr<MemoryBuffer>> loadFile(StringRef File) const;

  // Icon and cursor IDs are allocated starting from 1 and increasing for
  // each icon/cursor dumped. This maintains the current ID to be allocated.
  uint16_t IconCursorID;
};

} // namespace rc
} // namespace llvm

#endif
