//===-- DiffEngine.h - File comparator --------------------------*- 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 header defines the interface to the llvm-tapi difference engine,
// which structurally compares two tbd files.
//
//===----------------------------------------------------------------------===/
#ifndef LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H
#define LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H

#include "llvm/ADT/Optional.h"
#include "llvm/Object/TapiUniversal.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TextAPI/Symbol.h"
#include "llvm/TextAPI/Target.h"

namespace llvm {

/// InterfaceInputOrder determines from which file the diff attribute belongs
/// to.
enum InterfaceInputOrder { lhs, rhs };

/// DiffAttrKind is the enum that holds the concrete bases for RTTI.
enum DiffAttrKind {
  AD_Diff_Scalar_PackedVersion,
  AD_Diff_Scalar_Unsigned,
  AD_Diff_Scalar_Bool,
  AD_Diff_Scalar_Str,
  AD_Str_Vec,
  AD_Sym_Vec,
  AD_Inline_Doc,
};

/// AttributeDiff is the abstract class for RTTI.
class AttributeDiff {
public:
  AttributeDiff(DiffAttrKind Kind) : Kind(Kind){};
  virtual ~AttributeDiff(){};
  DiffAttrKind getKind() const { return Kind; }

private:
  DiffAttrKind Kind;
};

/// DiffOutput is the representation of a diff for a single attribute.
struct DiffOutput {
  /// The name of the attribute.
  std::string Name;
  /// The kind for RTTI
  DiffAttrKind Kind;
  /// Different values for the attribute
  /// from each file where a diff is present.
  std::vector<std::unique_ptr<AttributeDiff>> Values;
  DiffOutput(std::string Name) : Name(Name){};
};

/// DiffScalarVal is a template class for the different types of scalar values.
template <class T, DiffAttrKind U> class DiffScalarVal : public AttributeDiff {
public:
  DiffScalarVal(InterfaceInputOrder Order, T Val)
      : AttributeDiff(U), Order(Order), Val(Val){};

  static bool classof(const AttributeDiff *A) { return A->getKind() == U; }

  void print(raw_ostream &, std::string);

  T getVal() const { return Val; }
  InterfaceInputOrder getOrder() const { return Order; }

private:
  /// The order is the file from which the diff is found.
  InterfaceInputOrder Order;
  T Val;
};

/// SymScalar is the diff symbol and the order.
class SymScalar {
public:
  SymScalar(InterfaceInputOrder Order, const MachO::Symbol *Sym)
      : Order(Order), Val(Sym){};

  std::string getFlagString(MachO::SymbolFlags Flags) {
    return Flags != MachO::SymbolFlags::None
               ? " - " + stringifySymbolFlag(Flags)
               : stringifySymbolFlag(Flags);
  }

  void print(raw_ostream &OS, std::string Indent, MachO::Target Targ);

  const MachO::Symbol *getVal() const { return Val; }
  InterfaceInputOrder getOrder() const { return Order; }

private:
  /// The order is the file from which the diff is found.
  InterfaceInputOrder Order;
  const MachO::Symbol *Val;
  StringLiteral getSymbolNamePrefix(MachO::SymbolKind Kind);
  std::string stringifySymbolFlag(MachO::SymbolFlags Flag);
};

class DiffStrVec : public AttributeDiff {
public:
  MachO::Target Targ;
  /// Values is a vector of StringRef values associated with the target.
  std::vector<DiffScalarVal<StringRef, AD_Diff_Scalar_Str>> TargValues;
  DiffStrVec(MachO::Target Targ) : AttributeDiff(AD_Str_Vec), Targ(Targ){};

  static bool classof(const AttributeDiff *A) {
    return A->getKind() == AD_Str_Vec;
  }
};

class DiffSymVec : public AttributeDiff {
public:
  MachO::Target Targ;
  /// Values is a vector of symbol values associated with the target.
  std::vector<SymScalar> TargValues;
  DiffSymVec(MachO::Target Targ) : AttributeDiff(AD_Sym_Vec), Targ(Targ){};

  static bool classof(const AttributeDiff *A) {
    return A->getKind() == AD_Sym_Vec;
  }
};

/// InlineDoc represents an inlined framework/library in a TBD File.
class InlineDoc : public AttributeDiff {
public:
  /// Install name of the framework/library.
  std::string InstallName;
  /// Differences found from each file.
  std::vector<DiffOutput> DocValues;
  InlineDoc(StringRef InstName, std::vector<DiffOutput> Diff)
      : AttributeDiff(AD_Inline_Doc), InstallName(InstName),
        DocValues(std::move(Diff)){};

  static bool classof(const AttributeDiff *A) {
    return A->getKind() == AD_Inline_Doc;
  }
};

/// DiffEngine contains the methods to compare the input files and print the
/// output of the differences found in the files.
class DiffEngine {
public:
  DiffEngine(object::TapiUniversal *InputFileNameLHS,
             object::TapiUniversal *InputFileNameRHS)
      : FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){};
  bool compareFiles(raw_ostream &);

private:
  object::TapiUniversal *FileLHS;
  object::TapiUniversal *FileRHS;

  /// Function that prints the differences found in the files.
  void printDifferences(raw_ostream &, const std::vector<DiffOutput> &, int);
  /// Function that does the comparison of the TBD files and returns the
  /// differences.
  std::vector<DiffOutput> findDifferences(const MachO::InterfaceFile *,
                                          const MachO::InterfaceFile *);
};

} // namespace llvm

#endif
