// Copyright 2021 The Tint Authors.
//
// 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.

#include "src/tint/sem/constant.h"

#include <cmath>
#include <utility>

#include "src/tint/debug.h"
#include "src/tint/program_builder.h"
#include "src/tint/sem/type.h"

namespace tint::sem {

namespace {
size_t CountElements(const Constant::Elements& elements) {
    return std::visit([](auto&& vec) { return vec.size(); }, elements);
}

template <typename T>
bool IsNegativeFloat(T value) {
    (void)value;
    if constexpr (IsFloatingPoint<T>) {
        return std::signbit(value);
    } else {
        return false;
    }
}

}  // namespace

Constant::Constant() {}

Constant::Constant(const sem::Type* ty, Elements els)
    : type_(ty), elem_type_(CheckElemType(ty, CountElements(els))), elems_(std::move(els)) {}

Constant::Constant(const sem::Type* ty, AInts vec) : Constant(ty, Elements{std::move(vec)}) {}

Constant::Constant(const sem::Type* ty, AFloats vec) : Constant(ty, Elements{std::move(vec)}) {}

Constant::Constant(const Constant&) = default;

Constant::~Constant() = default;

Constant& Constant::operator=(const Constant& rhs) = default;

bool Constant::AnyZero() const {
    return WithElements([&](auto&& vec) {
        using T = typename std::decay_t<decltype(vec)>::value_type;
        for (auto el : vec) {
            if (el == T(0) && !IsNegativeFloat(el.value)) {
                return true;
            }
        }
        return false;
    });
}

bool Constant::AllZero(size_t start, size_t end) const {
    return WithElements([&](auto&& vec) {
        using T = typename std::decay_t<decltype(vec)>::value_type;
        for (size_t i = start; i < end; i++) {
            auto el = vec[i];
            if (el != T(0) || IsNegativeFloat(el.value)) {
                return false;
            }
        }
        return true;
    });
}

bool Constant::AllEqual(size_t start, size_t end) const {
    return WithElements([&](auto&& vec) {
        if (!vec.empty()) {
            auto value = vec[start];
            bool float_sign = IsNegativeFloat(vec[start].value);
            for (size_t i = start + 1; i < end; i++) {
                if (vec[i] != value || float_sign != IsNegativeFloat(vec[i].value)) {
                    return false;
                }
            }
        }
        return true;
    });
}

const Type* Constant::CheckElemType(const sem::Type* ty, size_t num_elements) {
    diag::List diag;
    uint32_t count = 0;
    auto* el_ty = Type::DeepestElementOf(ty, &count);
    if (!el_ty) {
        TINT_ICE(Semantic, diag) << "Unsupported sem::Constant type: " << ty->TypeInfo().name;
        return nullptr;
    }
    if (num_elements != count) {
        TINT_ICE(Semantic, diag) << "sem::Constant() type <-> element mismatch. type: '"
                                 << ty->TypeInfo().name << "' provided: " << num_elements
                                 << " require: " << count;
    }
    TINT_ASSERT(Semantic, el_ty->is_abstract_or_scalar());
    return el_ty;
}

}  // namespace tint::sem
