// 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/resolver/resolver.h"

#include "gmock/gmock.h"
#include "src/ast/struct_block_decoration.h"
#include "src/resolver/resolver_test_helper.h"
#include "src/sem/struct.h"

namespace tint {
namespace resolver {
namespace {

using ResolverHostShareableValidationTest = ResolverTest;

TEST_F(ResolverHostShareableValidationTest, BoolMember) {
  auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.bool_())},
                      {create<ast::StructBlockDecoration>()});

  Global(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage,
         ast::Access::kRead,
         ast::DecorationList{
             create<ast::BindingDecoration>(0),
             create<ast::GroupDecoration>(0),
         });

  ASSERT_FALSE(r()->Resolve());

  EXPECT_EQ(
      r()->error(),
      R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
12:34 note: while analysing structure member S.x
56:78 note: while instantiating variable g)");
}

TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) {
  auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.vec3<bool>())},
                      {create<ast::StructBlockDecoration>()});

  Global(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage,
         ast::Access::kRead,
         ast::DecorationList{
             create<ast::BindingDecoration>(0),
             create<ast::GroupDecoration>(0),
         });

  ASSERT_FALSE(r()->Resolve());

  EXPECT_EQ(
      r()->error(),
      R"(56:78 error: Type 'vec3<bool>' cannot be used in storage class 'storage' as it is non-host-shareable
12:34 note: while analysing structure member S.x
56:78 note: while instantiating variable g)");
}

TEST_F(ResolverHostShareableValidationTest, Aliases) {
  auto* a1 = Alias("a1", ty.bool_());
  auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.Of(a1))},
                      {create<ast::StructBlockDecoration>()});
  auto* a2 = Alias("a2", ty.Of(s));
  Global(Source{{56, 78}}, "g", ty.Of(a2), ast::StorageClass::kStorage,
         ast::Access::kRead,
         ast::DecorationList{
             create<ast::BindingDecoration>(0),
             create<ast::GroupDecoration>(0),
         });

  ASSERT_FALSE(r()->Resolve());

  EXPECT_EQ(
      r()->error(),
      R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
12:34 note: while analysing structure member S.x
56:78 note: while instantiating variable g)");
}

TEST_F(ResolverHostShareableValidationTest, NestedStructures) {
  auto* i1 = Structure("I1", {Member(Source{{1, 2}}, "x", ty.bool_())});
  auto* i2 = Structure("I2", {Member(Source{{3, 4}}, "y", ty.Of(i1))});
  auto* i3 = Structure("I3", {Member(Source{{5, 6}}, "z", ty.Of(i2))});

  auto* s = Structure("S", {Member(Source{{7, 8}}, "m", ty.Of(i3))},
                      {create<ast::StructBlockDecoration>()});

  Global(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage,
         ast::Access::kRead,
         ast::DecorationList{
             create<ast::BindingDecoration>(0),
             create<ast::GroupDecoration>(0),
         });

  ASSERT_FALSE(r()->Resolve());

  EXPECT_EQ(
      r()->error(),
      R"(9:10 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
1:2 note: while analysing structure member I1.x
3:4 note: while analysing structure member I2.y
5:6 note: while analysing structure member I3.z
7:8 note: while analysing structure member S.m
9:10 note: while instantiating variable g)");
}

TEST_F(ResolverHostShareableValidationTest, NoError) {
  auto* i1 =
      Structure("I1", {
                          Member(Source{{1, 1}}, "x1", ty.f32()),
                          Member(Source{{2, 1}}, "y1", ty.vec3<f32>()),
                          Member(Source{{3, 1}}, "z1", ty.array<i32, 4>()),
                      });
  auto* a1 = Alias("a1", ty.Of(i1));
  auto* i2 = Structure("I2", {
                                 Member(Source{{4, 1}}, "x2", ty.mat2x2<f32>()),
                                 Member(Source{{5, 1}}, "y2", ty.Of(i1)),
                             });
  auto* a2 = Alias("a2", ty.Of(i2));
  auto* i3 = Structure("I3", {
                                 Member(Source{{4, 1}}, "x3", ty.Of(a1)),
                                 Member(Source{{5, 1}}, "y3", ty.Of(i2)),
                                 Member(Source{{6, 1}}, "z3", ty.Of(a2)),
                             });

  auto* s = Structure("S", {Member(Source{{7, 8}}, "m", ty.Of(i3))},
                      {create<ast::StructBlockDecoration>()});

  Global(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage,
         ast::Access::kRead,
         ast::DecorationList{
             create<ast::BindingDecoration>(0),
             create<ast::GroupDecoration>(0),
         });
  WrapInFunction();

  ASSERT_TRUE(r()->Resolve()) << r()->error();
}

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