// Copyright 2023 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "gmock/gmock.h"

#include "src/tint/lang/core/fluent_types.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"

using namespace tint::core::number_suffixes;  // NOLINT
using namespace tint::core::fluent_types;     // NOLINT

namespace tint::resolver {
namespace {

using ResolverUnresolvedIdentifierSuggestions = ResolverTest;

TEST_F(ResolverUnresolvedIdentifierSuggestions, AddressSpace) {
    AST().AddGlobalVariable(create<ast::Var>(
        Ident("v"),                        // name
        ty.i32(),                          // type
        Expr(Source{{12, 34}}, "privte"),  // declared_address_space
        nullptr,                           // declared_access
        nullptr,                           // initializer
        tint::Empty                        // attributes
        ));

    EXPECT_FALSE(r()->Resolve());
    EXPECT_EQ(r()->error(), R"(12:34 error: unresolved address space 'privte'
12:34 note: Did you mean 'private'?
Possible values: 'function', 'pixel_local', 'private', 'push_constant', 'storage', 'uniform', 'workgroup')");
}

TEST_F(ResolverUnresolvedIdentifierSuggestions, BuiltinValue) {
    Func("f", Vector{Param("p", ty.i32(), Vector{Builtin(Expr(Source{{12, 34}}, "positon"))})},
         ty.void_(), tint::Empty, Vector{Stage(ast::PipelineStage::kVertex)});

    EXPECT_FALSE(r()->Resolve());
    EXPECT_EQ(r()->error(), R"(12:34 error: unresolved builtin value 'positon'
12:34 note: Did you mean 'position'?
Possible values: 'frag_depth', 'front_facing', 'global_invocation_id', 'instance_index', 'local_invocation_id', 'local_invocation_index', 'num_workgroups', 'position', 'sample_index', 'sample_mask', 'subgroup_invocation_id', 'subgroup_size', 'vertex_index', 'workgroup_id')");
}

TEST_F(ResolverUnresolvedIdentifierSuggestions, TexelFormat) {
    GlobalVar("v", ty("texture_storage_1d", Expr(Source{{12, 34}}, "rba8unorm"), "read"));

    EXPECT_FALSE(r()->Resolve());
    EXPECT_EQ(r()->error(), R"(12:34 error: unresolved texel format 'rba8unorm'
12:34 note: Did you mean 'rgba8unorm'?
Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
}

TEST_F(ResolverUnresolvedIdentifierSuggestions, AccessMode) {
    AST().AddGlobalVariable(create<ast::Var>(Ident("v"),       // name
                                             ty.i32(),         // type
                                             Expr("private"),  // declared_address_space
                                             Expr(Source{{12, 34}}, "reed"),  // declared_access
                                             nullptr,                         // initializer
                                             tint::Empty                      // attributes
                                             ));

    EXPECT_FALSE(r()->Resolve());
    EXPECT_EQ(r()->error(), R"(12:34 error: unresolved access 'reed'
12:34 note: Did you mean 'read'?
Possible values: 'read', 'read_write', 'write')");
}

TEST_F(ResolverUnresolvedIdentifierSuggestions, InterpolationSampling) {
    Structure("s", Vector{
                       Member("m", ty.vec4<f32>(),
                              Vector{
                                  Interpolate(core::InterpolationType::kLinear,
                                              Expr(Source{{12, 34}}, "centre")),
                              }),
                   });

    EXPECT_FALSE(r()->Resolve());
    EXPECT_EQ(r()->error(), R"(12:34 error: unresolved interpolation sampling 'centre'
12:34 note: Did you mean 'center'?
Possible values: 'center', 'centroid', 'sample')");
}

TEST_F(ResolverUnresolvedIdentifierSuggestions, InterpolationType) {
    Structure("s", Vector{
                       Member("m", ty.vec4<f32>(),
                              Vector{
                                  Interpolate(Expr(Source{{12, 34}}, "liner")),
                              }),
                   });

    EXPECT_FALSE(r()->Resolve());
    EXPECT_EQ(r()->error(), R"(12:34 error: unresolved interpolation type 'liner'
12:34 note: Did you mean 'linear'?
Possible values: 'flat', 'linear', 'perspective')");
}

}  // namespace
}  // namespace tint::resolver
