# Copyright 2015 The Shaderc Authors. All rights reserved.
#
# 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.

import expect
from glslc_test_framework import inside_glslc_testsuite
from placeholder import FileShader


def assembly_comments():
    return """
    ; SPIR-V
    ; Version: 1.0
    ; Generator: Google Shaderc over Glslang; 10
    ; Bound: 6
    ; Schema: 0"""


def empty_main_assembly():
    return assembly_comments() + """
         OpCapability Shader
    %1 = OpExtInstImport "GLSL.std.450"
         OpMemoryModel Logical GLSL450
         OpEntryPoint Vertex %4 "main"
         OpSource ESSL 310
         OpName %4 "main"
    %2 = OpTypeVoid
    %3 = OpTypeFunction %2
    %4 = OpFunction %2 None %3
    %5 = OpLabel
         OpReturn
         OpFunctionEnd"""


def empty_main():
    return '#version 310 es\nvoid main() {}'


@inside_glslc_testsuite('SpirvAssembly')
class TestAssemblyFileAsOnlyParameter(expect.ValidNamedObjectFile):
    """Tests that glslc accepts a SPIR-V assembly file as the only parameter."""

    shader = FileShader(empty_main_assembly(), '.spvasm')
    glslc_args = [shader]
    expected_object_filenames = ('a.spv',)


@inside_glslc_testsuite('SpirvAssembly')
class TestDashCAssemblyFile(expect.ValidObjectFile):
    """Tests that -c works with SPIR-V assembly file."""

    shader = FileShader(empty_main_assembly(), '.spvasm')
    glslc_args = ['-c', shader]


@inside_glslc_testsuite('SpirvAssembly')
class TestAssemblyFileWithOnlyComments(expect.ValidObjectFile):
    """Tests that glslc accepts an assembly file with only comments inside."""

    shader = FileShader(assembly_comments(), '.spvasm')
    glslc_args = ['-c', shader]


@inside_glslc_testsuite('SpirvAssembly')
class TestEmptyAssemblyFile(expect.ValidObjectFile):
    """Tests that glslc accepts an empty assembly file."""

    shader = FileShader('', '.spvasm')
    glslc_args = ['-c', shader]


@inside_glslc_testsuite('SpirvAssembly')
class TestDashEAssemblyFile(expect.SuccessfulReturn, expect.NoGeneratedFiles):
    """Tests that -E works with SPIR-V assembly file."""

    shader = FileShader(empty_main_assembly(), '.spvasm')
    glslc_args = ['-E', shader]


@inside_glslc_testsuite('SpirvAssembly')
class TestDashSAssemblyFile(expect.SuccessfulReturn, expect.NoGeneratedFiles):
    """Tests that -S works with SPIR-V assembly file."""

    shader = FileShader(empty_main_assembly(), '.spvasm')
    glslc_args = ['-S', shader]


@inside_glslc_testsuite('SpirvAssembly')
class TestMultipleAssemblyFiles(expect.ValidObjectFile):
    """Tests that glslc accepts multiple SPIR-V assembly files."""

    shader1 = FileShader(empty_main_assembly(), '.spvasm')
    shader2 = FileShader(empty_main_assembly(), '.spvasm')
    shader3 = FileShader(empty_main_assembly(), '.spvasm')
    glslc_args = ['-c', shader1, shader2, shader3]


@inside_glslc_testsuite('SpirvAssembly')
class TestHybridInputFiles(expect.ValidObjectFile):
    """Tests that glslc accepts a mix of SPIR-V assembly files and
    GLSL source files."""

    shader1 = FileShader(empty_main_assembly(), '.spvasm')
    shader2 = FileShader(empty_main(), '.vert')
    shader3 = FileShader(empty_main(), '.frag')
    glslc_args = ['-c', shader1, shader2, shader3]


@inside_glslc_testsuite('SpirvAssembly')
class TestShaderStageWithAssemblyFile(expect.ErrorMessage):
    """Tests that assembly files don't work with -fshader-stage"""

    shader = FileShader(empty_main_assembly(), '.spvasm')
    glslc_args = ['-c', '-fshader-stage=vertex', shader]

    expected_error = [
        shader, ": error: #version: Desktop shaders for Vulkan SPIR-V require "
        "version 140 or higher\n",
        shader, ":2: error: 'extraneous semicolon' :",
        " not supported for this version or the enabled extensions\n",
        shader, ":2: error: '' :  syntax error, unexpected IDENTIFIER\n",
        '3 errors generated.\n']


@inside_glslc_testsuite('SpirvAssembly')
class TestStdWithAssemblyFile(expect.ValidObjectFile):
    """Tests that --std= doesn't affect the processing of assembly files."""

    shader = FileShader(empty_main_assembly(), '.spvasm')
    glslc_args = ['-c', '-std=310es', shader]
