/**
 * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
 **/ export const description = `
createBindGroupLayout validation tests.

TODO: review existing tests, write descriptions, and make sure tests are complete.
`;
import { pbool, poptions, params } from '../../../common/framework/params_builder.js';
import { makeTestGroup } from '../../../common/framework/test_group.js';
import {
  kBindingTypeInfo,
  kBindingTypes,
  kBufferBindingTypeInfo,
  kMaxBindingsPerBindGroup,
  kShaderStages,
  kShaderStageCombinations,
  kTextureBindingTypeInfo,
  kTextureComponentTypes,
  kTextureViewDimensions,
  kTextureViewDimensionInfo,
  kAllTextureFormats,
  kAllTextureFormatInfo,
} from '../../capability_info.js';

import { ValidationTest } from './validation_test.js';

function clone(descriptor) {
  return JSON.parse(JSON.stringify(descriptor));
}

export const g = makeTestGroup(ValidationTest);

g.test('some_binding_index_was_specified_more_than_once').fn(async t => {
  const goodDescriptor = {
    entries: [
      { binding: 0, visibility: GPUShaderStage.COMPUTE, type: 'storage-buffer' },
      { binding: 1, visibility: GPUShaderStage.COMPUTE, type: 'storage-buffer' },
    ],
  };

  // Control case
  t.device.createBindGroupLayout(goodDescriptor);

  const badDescriptor = clone(goodDescriptor);
  badDescriptor.entries[1].binding = 0;

  // Binding index 0 can't be specified twice.
  t.expectValidationError(() => {
    t.device.createBindGroupLayout(badDescriptor);
  });
});

g.test('visibility')
  .params(
    params()
      .combine(poptions('type', kBindingTypes))
      .combine(poptions('visibility', kShaderStageCombinations))
  )
  .fn(async t => {
    const { type, visibility } = t.params;

    const info = kBindingTypeInfo[type];
    const storageTextureFormat = info.resource === 'storageTex' ? 'rgba8unorm' : undefined;

    const success = (visibility & ~kBindingTypeInfo[type].validStages) === 0;

    t.expectValidationError(() => {
      t.device.createBindGroupLayout({
        entries: [{ binding: 0, visibility, type, storageTextureFormat }],
      });
    }, !success);
  });

g.test('bindingTypeSpecific_optional_members')
  .params(
    params()
      .combine(poptions('type', kBindingTypes))
      .combine([
        // Case with every member set to `undefined`.
        {
          // Workaround for TS inferring the type of [ {}, ...x ] overly conservatively, as {}[].
          _: 0,
        },

        // Cases with one member set.
        ...pbool('hasDynamicOffset'),
        ...poptions('minBufferBindingSize', [0, 4]),
        ...poptions('textureComponentType', kTextureComponentTypes),
        ...poptions('viewDimension', kTextureViewDimensions),
        ...poptions('storageTextureFormat', kAllTextureFormats),
      ])
  )
  .fn(t => {
    const {
      type,
      hasDynamicOffset,
      minBufferBindingSize,
      textureComponentType,
      viewDimension,
      storageTextureFormat,
    } = t.params;

    let success = true;
    if (!(type in kBufferBindingTypeInfo)) {
      success && (success = hasDynamicOffset === undefined);
      success && (success = minBufferBindingSize === undefined);
    }
    if (!(type in kTextureBindingTypeInfo)) {
      success && (success = viewDimension === undefined);
    }
    if (kBindingTypeInfo[type].resource !== 'sampledTex') {
      success && (success = textureComponentType === undefined);
    }
    if (kBindingTypeInfo[type].resource !== 'storageTex') {
      success && (success = storageTextureFormat === undefined);
    } else {
      success &&
        (success = viewDimension === undefined || kTextureViewDimensionInfo[viewDimension].storage);
      success &&
        (success =
          storageTextureFormat === undefined ||
          kAllTextureFormatInfo[storageTextureFormat].storage);
    }

    t.expectValidationError(() => {
      t.device.createBindGroupLayout({
        entries: [
          {
            binding: 0,
            visibility: GPUShaderStage.COMPUTE,
            type,
            hasDynamicOffset,
            minBufferBindingSize,
            textureComponentType,
            viewDimension,
            storageTextureFormat,
          },
        ],
      });
    }, !success);
  });

g.test('multisample_requires_2d_view_dimension')
  .params(params().combine(poptions('viewDimension', [undefined, ...kTextureViewDimensions])))
  .fn(async t => {
    const { viewDimension } = t.params;

    const success = viewDimension === '2d' || viewDimension === undefined;

    t.expectValidationError(() => {
      t.device.createBindGroupLayout({
        entries: [
          {
            binding: 0,
            visibility: GPUShaderStage.COMPUTE,
            type: 'multisampled-texture',
            viewDimension,
          },
        ],
      });
    }, !success);
  });

g.test('number_of_dynamic_buffers_exceeds_the_maximum_value')
  .desc(
    `TODO: describe

TODO(#230): Update to enforce per-stage and per-pipeline-layout limits on BGLs as well.`
  )
  .params([
    { type: 'storage-buffer', maxDynamicBufferCount: 4 },
    { type: 'uniform-buffer', maxDynamicBufferCount: 8 },
  ])
  .fn(async t => {
    const { type, maxDynamicBufferCount } = t.params;

    const maxDynamicBufferBindings = [];
    for (let i = 0; i < maxDynamicBufferCount; i++) {
      maxDynamicBufferBindings.push({
        binding: i,
        visibility: GPUShaderStage.COMPUTE,
        type,
        hasDynamicOffset: true,
      });
    }

    const goodDescriptor = {
      entries: [
        ...maxDynamicBufferBindings,
        {
          binding: maxDynamicBufferBindings.length,
          visibility: GPUShaderStage.COMPUTE,
          type,
          hasDynamicOffset: false,
        },
      ],
    };

    // Control case
    t.device.createBindGroupLayout(goodDescriptor);

    // Dynamic buffers exceed maximum in a bind group layout.
    const badDescriptor = clone(goodDescriptor);
    badDescriptor.entries[maxDynamicBufferCount].hasDynamicOffset = true;

    t.expectValidationError(() => {
      t.device.createBindGroupLayout(badDescriptor);
    });
  });

// One bind group layout will be filled with kPerStageBindingLimit[...] of the type |type|.
// For each item in the array returned here, a case will be generated which tests a pipeline
// layout with one extra bind group layout with one extra binding. That extra binding will have:
//
//   - If extraTypeSame, any of the binding types which counts toward the same limit as |type|.
//     (i.e. 'storage-buffer' <-> 'readonly-storage-buffer').
//   - Otherwise, an arbitrary other type.
function* pickExtraBindingTypes(bindingType, extraTypeSame) {
  const info = kBindingTypeInfo[bindingType];
  if (extraTypeSame) {
    for (const extraBindingType of kBindingTypes) {
      if (
        info.perStageLimitClass.class ===
        kBindingTypeInfo[extraBindingType].perStageLimitClass.class
      ) {
        yield extraBindingType;
      }
    }
  } else {
    yield info.perStageLimitClass.class === 'sampler' ? 'sampled-texture' : 'sampler';
  }
}

const kCasesForMaxResourcesPerStageTests = params()
  .combine(poptions('maxedType', kBindingTypes))
  .combine(poptions('maxedVisibility', kShaderStages))
  .filter(p => (kBindingTypeInfo[p.maxedType].validStages & p.maxedVisibility) !== 0)
  .expand(function* (p) {
    for (const extraTypeSame of [true, false]) {
      yield* poptions('extraType', pickExtraBindingTypes(p.maxedType, extraTypeSame));
    }
  })
  .combine(poptions('extraVisibility', kShaderStages))
  .filter(p => (kBindingTypeInfo[p.extraType].validStages & p.extraVisibility) !== 0);

// Should never fail unless kMaxBindingsPerBindGroup is exceeded, because the validation for
// resources-of-type-per-stage is in pipeline layout creation.
g.test('max_resources_per_stage,in_bind_group_layout')
  .desc(
    `TODO: describe

TODO(#230): Update to enforce per-stage and per-pipeline-layout limits on BGLs as well.`
  )
  .params(kCasesForMaxResourcesPerStageTests)
  .fn(async t => {
    const { maxedType, extraType, maxedVisibility, extraVisibility } = t.params;
    const maxedTypeInfo = kBindingTypeInfo[maxedType];
    const maxedCount = maxedTypeInfo.perStageLimitClass.max;
    const extraTypeInfo = kBindingTypeInfo[extraType];

    const maxResourceBindings = [];
    for (let i = 0; i < maxedCount; i++) {
      maxResourceBindings.push({
        binding: i,
        visibility: maxedVisibility,
        type: maxedType,
        storageTextureFormat: maxedTypeInfo.resource === 'storageTex' ? 'rgba8unorm' : undefined,
      });
    }

    const goodDescriptor = { entries: maxResourceBindings };

    // Control
    t.device.createBindGroupLayout(goodDescriptor);

    const newDescriptor = clone(goodDescriptor);
    newDescriptor.entries.push({
      binding: maxedCount,
      visibility: extraVisibility,
      type: extraType,
      storageTextureFormat: extraTypeInfo.resource === 'storageTex' ? 'rgba8unorm' : undefined,
    });

    const shouldError = maxedCount >= kMaxBindingsPerBindGroup;

    t.expectValidationError(() => {
      t.device.createBindGroupLayout(newDescriptor);
    }, shouldError);
  });

// One pipeline layout can have a maximum number of each type of binding *per stage* (which is
// different for each type). Test that the max works, then add one more binding of same-or-different
// type and same-or-different visibility.
g.test('max_resources_per_stage,in_pipeline_layout')
  .params(kCasesForMaxResourcesPerStageTests)
  .fn(async t => {
    const { maxedType, extraType, maxedVisibility, extraVisibility } = t.params;
    const maxedTypeInfo = kBindingTypeInfo[maxedType];
    const maxedCount = maxedTypeInfo.perStageLimitClass.max;
    const extraTypeInfo = kBindingTypeInfo[extraType];

    const maxResourceBindings = [];
    for (let i = 0; i < maxedCount; i++) {
      maxResourceBindings.push({
        binding: i,
        visibility: maxedVisibility,
        type: maxedType,
        storageTextureFormat: maxedTypeInfo.resource === 'storageTex' ? 'rgba8unorm' : undefined,
      });
    }

    const goodLayout = t.device.createBindGroupLayout({ entries: maxResourceBindings });

    // Control
    t.device.createPipelineLayout({ bindGroupLayouts: [goodLayout] });

    const extraLayout = t.device.createBindGroupLayout({
      entries: [
        {
          binding: 0,
          visibility: extraVisibility,
          type: extraType,
          storageTextureFormat: extraTypeInfo.resource === 'storageTex' ? 'rgba8unorm' : undefined,
        },
      ],
    });

    // Some binding types use the same limit, e.g. 'storage-buffer' and 'readonly-storage-buffer'.
    const newBindingCountsTowardSamePerStageLimit =
      (maxedVisibility & extraVisibility) !== 0 &&
      kBindingTypeInfo[maxedType].perStageLimitClass.class ===
        kBindingTypeInfo[extraType].perStageLimitClass.class;
    const layoutExceedsPerStageLimit = newBindingCountsTowardSamePerStageLimit;

    t.expectValidationError(() => {
      t.device.createPipelineLayout({ bindGroupLayouts: [goodLayout, extraLayout] });
    }, layoutExceedsPerStageLimit);
  });
