//===-- runtime/tools.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
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_RUNTIME_TOOLS_H_
#define FORTRAN_RUNTIME_TOOLS_H_

#include "terminator.h"
#include "flang/Common/long-double.h"
#include "flang/Runtime/cpp-type.h"
#include "flang/Runtime/descriptor.h"
#include "flang/Runtime/memory.h"
#include <functional>
#include <map>
#include <type_traits>

namespace Fortran::runtime {

class Terminator;

std::size_t TrimTrailingSpaces(const char *, std::size_t);

OwningPtr<char> SaveDefaultCharacter(
    const char *, std::size_t, const Terminator &);

// For validating and recognizing default CHARACTER values in a
// case-insensitive manner.  Returns the zero-based index into the
// null-terminated array of upper-case possibilities when the value is valid,
// or -1 when it has no match.
int IdentifyValue(
    const char *value, std::size_t length, const char *possibilities[]);

// Truncates or pads as necessary
void ToFortranDefaultCharacter(
    char *to, std::size_t toLength, const char *from);

// Utility for dealing with elemental LOGICAL arguments
inline bool IsLogicalElementTrue(
    const Descriptor &logical, const SubscriptValue at[]) {
  // A LOGICAL value is false if and only if all of its bytes are zero.
  const char *p{logical.Element<char>(at)};
  for (std::size_t j{logical.ElementBytes()}; j-- > 0; ++p) {
    if (*p) {
      return true;
    }
  }
  return false;
}

// Check array conformability; a scalar 'x' conforms.  Crashes on error.
void CheckConformability(const Descriptor &to, const Descriptor &x,
    Terminator &, const char *funcName, const char *toName,
    const char *fromName);

// Validate a KIND= argument
void CheckIntegerKind(Terminator &, int kind, const char *intrinsic);

template <typename TO, typename FROM>
inline void PutContiguousConverted(TO *to, FROM *from, std::size_t count) {
  while (count-- > 0) {
    *to++ = *from++;
  }
}

static inline std::int64_t GetInt64(
    const char *p, std::size_t bytes, Terminator &terminator) {
  switch (bytes) {
  case 1:
    return *reinterpret_cast<const CppTypeFor<TypeCategory::Integer, 1> *>(p);
  case 2:
    return *reinterpret_cast<const CppTypeFor<TypeCategory::Integer, 2> *>(p);
  case 4:
    return *reinterpret_cast<const CppTypeFor<TypeCategory::Integer, 4> *>(p);
  case 8:
    return *reinterpret_cast<const CppTypeFor<TypeCategory::Integer, 8> *>(p);
  default:
    terminator.Crash("GetInt64: no case for %zd bytes", bytes);
  }
}

template <typename INT>
inline bool SetInteger(INT &x, int kind, std::int64_t value) {
  switch (kind) {
  case 1:
    reinterpret_cast<CppTypeFor<TypeCategory::Integer, 1> &>(x) = value;
    return true;
  case 2:
    reinterpret_cast<CppTypeFor<TypeCategory::Integer, 2> &>(x) = value;
    return true;
  case 4:
    reinterpret_cast<CppTypeFor<TypeCategory::Integer, 4> &>(x) = value;
    return true;
  case 8:
    reinterpret_cast<CppTypeFor<TypeCategory::Integer, 8> &>(x) = value;
    return true;
  default:
    return false;
  }
}

// Maps intrinsic runtime type category and kind values to the appropriate
// instantiation of a function object template and calls it with the supplied
// arguments.
template <template <TypeCategory, int> class FUNC, typename RESULT,
    typename... A>
inline RESULT ApplyType(
    TypeCategory cat, int kind, Terminator &terminator, A &&...x) {
  switch (cat) {
  case TypeCategory::Integer:
    switch (kind) {
    case 1:
      return FUNC<TypeCategory::Integer, 1>{}(std::forward<A>(x)...);
    case 2:
      return FUNC<TypeCategory::Integer, 2>{}(std::forward<A>(x)...);
    case 4:
      return FUNC<TypeCategory::Integer, 4>{}(std::forward<A>(x)...);
    case 8:
      return FUNC<TypeCategory::Integer, 8>{}(std::forward<A>(x)...);
#ifdef __SIZEOF_INT128__
    case 16:
      return FUNC<TypeCategory::Integer, 16>{}(std::forward<A>(x)...);
#endif
    default:
      terminator.Crash("unsupported INTEGER(KIND=%d)", kind);
    }
  case TypeCategory::Real:
    switch (kind) {
#if 0 // TODO: REAL(2 & 3)
    case 2:
      return FUNC<TypeCategory::Real, 2>{}(std::forward<A>(x)...);
    case 3:
      return FUNC<TypeCategory::Real, 3>{}(std::forward<A>(x)...);
#endif
    case 4:
      return FUNC<TypeCategory::Real, 4>{}(std::forward<A>(x)...);
    case 8:
      return FUNC<TypeCategory::Real, 8>{}(std::forward<A>(x)...);
#if LONG_DOUBLE == 80
    case 10:
      return FUNC<TypeCategory::Real, 10>{}(std::forward<A>(x)...);
#elif LONG_DOUBLE == 128
    case 16:
      return FUNC<TypeCategory::Real, 16>{}(std::forward<A>(x)...);
#endif
    default:
      terminator.Crash("unsupported REAL(KIND=%d)", kind);
    }
  case TypeCategory::Complex:
    switch (kind) {
#if 0 // TODO: COMPLEX(2 & 3)
    case 2:
      return FUNC<TypeCategory::Complex, 2>{}(std::forward<A>(x)...);
    case 3:
      return FUNC<TypeCategory::Complex, 3>{}(std::forward<A>(x)...);
#endif
    case 4:
      return FUNC<TypeCategory::Complex, 4>{}(std::forward<A>(x)...);
    case 8:
      return FUNC<TypeCategory::Complex, 8>{}(std::forward<A>(x)...);
#if LONG_DOUBLE == 80
    case 10:
      return FUNC<TypeCategory::Complex, 10>{}(std::forward<A>(x)...);
#elif LONG_DOUBLE == 128
    case 16:
      return FUNC<TypeCategory::Complex, 16>{}(std::forward<A>(x)...);
#endif
    default:
      terminator.Crash("unsupported COMPLEX(KIND=%d)", kind);
    }
  case TypeCategory::Character:
    switch (kind) {
    case 1:
      return FUNC<TypeCategory::Character, 1>{}(std::forward<A>(x)...);
    case 2:
      return FUNC<TypeCategory::Character, 2>{}(std::forward<A>(x)...);
    case 4:
      return FUNC<TypeCategory::Character, 4>{}(std::forward<A>(x)...);
    default:
      terminator.Crash("unsupported CHARACTER(KIND=%d)", kind);
    }
  case TypeCategory::Logical:
    switch (kind) {
    case 1:
      return FUNC<TypeCategory::Logical, 1>{}(std::forward<A>(x)...);
    case 2:
      return FUNC<TypeCategory::Logical, 2>{}(std::forward<A>(x)...);
    case 4:
      return FUNC<TypeCategory::Logical, 4>{}(std::forward<A>(x)...);
    case 8:
      return FUNC<TypeCategory::Logical, 8>{}(std::forward<A>(x)...);
    default:
      terminator.Crash("unsupported LOGICAL(KIND=%d)", kind);
    }
  default:
    terminator.Crash("unsupported type category(%d)", static_cast<int>(cat));
  }
}

// Maps a runtime INTEGER kind value to the appropriate instantiation of
// a function object template and calls it with the supplied arguments.
template <template <int KIND> class FUNC, typename RESULT, typename... A>
inline RESULT ApplyIntegerKind(int kind, Terminator &terminator, A &&...x) {
  switch (kind) {
  case 1:
    return FUNC<1>{}(std::forward<A>(x)...);
  case 2:
    return FUNC<2>{}(std::forward<A>(x)...);
  case 4:
    return FUNC<4>{}(std::forward<A>(x)...);
  case 8:
    return FUNC<8>{}(std::forward<A>(x)...);
#ifdef __SIZEOF_INT128__
  case 16:
    return FUNC<16>{}(std::forward<A>(x)...);
#endif
  default:
    terminator.Crash("unsupported INTEGER(KIND=%d)", kind);
  }
}

template <template <int KIND> class FUNC, typename RESULT, typename... A>
inline RESULT ApplyFloatingPointKind(
    int kind, Terminator &terminator, A &&...x) {
  switch (kind) {
#if 0 // TODO: REAL/COMPLEX (2 & 3)
  case 2:
    return FUNC<2>{}(std::forward<A>(x)...);
  case 3:
    return FUNC<3>{}(std::forward<A>(x)...);
#endif
  case 4:
    return FUNC<4>{}(std::forward<A>(x)...);
  case 8:
    return FUNC<8>{}(std::forward<A>(x)...);
#if LONG_DOUBLE == 80
  case 10:
    return FUNC<10>{}(std::forward<A>(x)...);
#elif LONG_DOUBLE == 128
  case 16:
    return FUNC<16>{}(std::forward<A>(x)...);
#endif
  default:
    terminator.Crash("unsupported REAL/COMPLEX(KIND=%d)", kind);
  }
}

template <template <int KIND> class FUNC, typename RESULT, typename... A>
inline RESULT ApplyCharacterKind(int kind, Terminator &terminator, A &&...x) {
  switch (kind) {
  case 1:
    return FUNC<1>{}(std::forward<A>(x)...);
  case 2:
    return FUNC<2>{}(std::forward<A>(x)...);
  case 4:
    return FUNC<4>{}(std::forward<A>(x)...);
  default:
    terminator.Crash("unsupported CHARACTER(KIND=%d)", kind);
  }
}

template <template <int KIND> class FUNC, typename RESULT, typename... A>
inline RESULT ApplyLogicalKind(int kind, Terminator &terminator, A &&...x) {
  switch (kind) {
  case 1:
    return FUNC<1>{}(std::forward<A>(x)...);
  case 2:
    return FUNC<2>{}(std::forward<A>(x)...);
  case 4:
    return FUNC<4>{}(std::forward<A>(x)...);
  case 8:
    return FUNC<8>{}(std::forward<A>(x)...);
  default:
    terminator.Crash("unsupported LOGICAL(KIND=%d)", kind);
  }
}

// Calculate result type of (X op Y) for *, //, DOT_PRODUCT, &c.
std::optional<std::pair<TypeCategory, int>> inline constexpr GetResultType(
    TypeCategory xCat, int xKind, TypeCategory yCat, int yKind) {
  int maxKind{std::max(xKind, yKind)};
  switch (xCat) {
  case TypeCategory::Integer:
    switch (yCat) {
    case TypeCategory::Integer:
      return std::make_pair(TypeCategory::Integer, maxKind);
    case TypeCategory::Real:
    case TypeCategory::Complex:
      return std::make_pair(yCat, yKind);
    default:
      break;
    }
    break;
  case TypeCategory::Real:
    switch (yCat) {
    case TypeCategory::Integer:
      return std::make_pair(TypeCategory::Real, xKind);
    case TypeCategory::Real:
    case TypeCategory::Complex:
      return std::make_pair(yCat, maxKind);
    default:
      break;
    }
    break;
  case TypeCategory::Complex:
    switch (yCat) {
    case TypeCategory::Integer:
      return std::make_pair(TypeCategory::Complex, xKind);
    case TypeCategory::Real:
    case TypeCategory::Complex:
      return std::make_pair(TypeCategory::Complex, maxKind);
    default:
      break;
    }
    break;
  case TypeCategory::Character:
    if (yCat == TypeCategory::Character) {
      return std::make_pair(TypeCategory::Character, maxKind);
    } else {
      return std::nullopt;
    }
  case TypeCategory::Logical:
    if (yCat == TypeCategory::Logical) {
      return std::make_pair(TypeCategory::Logical, maxKind);
    } else {
      return std::nullopt;
    }
  default:
    break;
  }
  return std::nullopt;
}

// Accumulate floating-point results in (at least) double precision
template <TypeCategory CAT, int KIND>
using AccumulationType = CppTypeFor<CAT,
    CAT == TypeCategory::Real || CAT == TypeCategory::Complex
        ? std::max(KIND, static_cast<int>(sizeof(double)))
        : KIND>;

} // namespace Fortran::runtime
#endif // FORTRAN_RUNTIME_TOOLS_H_
