/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_CMDLINE_DETAIL_CMDLINE_PARSER_DETAIL_H_
#define ART_CMDLINE_DETAIL_CMDLINE_PARSER_DETAIL_H_

#include <string>
#include <sstream>
#include <vector>

namespace art {
  // Implementation details for some template querying. Don't look inside if you hate templates.
  namespace detail {
    template <typename T>
    typename std::remove_reference<T>::type& FakeReference();

    // SupportsInsertionOperator<T, TStream>::value will evaluate to a boolean,
    // whose value is true if the TStream class supports the << operator against T,
    // and false otherwise.
    template <typename T2, typename TStream2 = std::ostream>
    struct SupportsInsertionOperator {
     private:
      template <typename TStream, typename T>
      static std::true_type InsertionOperatorTest(TStream& os, const T& value,
                                                  std::remove_reference<decltype(os << value)>* = 0);  // NOLINT [whitespace/operators] [3]

      template <typename TStream, typename ... T>
      static std::false_type InsertionOperatorTest(TStream& os, const T& ... args);

     public:
      static constexpr bool value =
          decltype(InsertionOperatorTest(FakeReference<TStream2>(), std::declval<T2>()))::value;
    };

    template <typename TLeft, typename TRight = TLeft, bool IsFloatingPoint = false>
    struct SupportsEqualityOperatorImpl;

    template <typename TLeft, typename TRight>
    struct SupportsEqualityOperatorImpl<TLeft, TRight, false> {
     private:
      template <typename TL, typename TR>
      static std::true_type EqualityOperatorTest(const TL& left, const TR& right,
                                                 std::remove_reference<decltype(left == right)>* = 0);  // NOLINT [whitespace/operators] [3]

      template <typename TL, typename ... T>
      static std::false_type EqualityOperatorTest(const TL& left, const T& ... args);

     public:
      static constexpr bool value =
          decltype(EqualityOperatorTest(std::declval<TLeft>(), std::declval<TRight>()))::value;
    };

    // Partial specialization when TLeft/TRight are both floating points.
    // This is a work-around because decltype(floatvar1 == floatvar2)
    // will not compile with clang:
    // error: comparing floating point with == or != is unsafe [-Werror,-Wfloat-equal]
    template <typename TLeft, typename TRight>
    struct SupportsEqualityOperatorImpl<TLeft, TRight, true> {
      static constexpr bool value = true;
    };

    // SupportsEqualityOperatorImpl<T1, T2>::value will evaluate to a boolean,
    // whose value is true if T1 can be compared against T2 with ==,
    // and false otherwise.
    template <typename TLeft, typename TRight = TLeft>
    struct SupportsEqualityOperator :
        SupportsEqualityOperatorImpl<TLeft, TRight,
                                     std::is_floating_point<TLeft>::value
                                     && std::is_floating_point<TRight>::value> {
    };

    // Convert any kind of type to an std::string, even if there's no
    // serialization support for it. Unknown types get converted to an
    // an arbitrary value.
    //
    // Meant for printing user-visible errors or unit test failures only.
    template <typename T>
    std::string ToStringAny(const T& value,
                            typename std::enable_if<
                                SupportsInsertionOperator<T>::value>::type* = 0) {
      std::stringstream stream;
      stream << value;
      return stream.str();
    }

    template <typename T>
    std::string ToStringAny(const std::vector<T> value,
                            typename std::enable_if<
                                SupportsInsertionOperator<T>::value>::type* = 0) {
      std::stringstream stream;
      stream << "vector{";

      for (size_t i = 0; i < value.size(); ++i) {
        stream << ToStringAny(value[i]);

        if (i != value.size() - 1) {
          stream << ',';
        }
      }

      stream << "}";
      return stream.str();
    }

    template <typename T>
    std::string ToStringAny(const T&,
                            typename std::enable_if<
                                !SupportsInsertionOperator<T>::value>::type* = 0
    ) {
      return std::string("(unknown type [no operator<< implemented] for )");
    }
  }  // namespace detail  // NOLINT [readability/namespace] [5]
}  // namespace art

#endif  // ART_CMDLINE_DETAIL_CMDLINE_PARSER_DETAIL_H_
