import argparse
import glob
import io
import os
import re
import sys
from collections import defaultdict

parser = argparse.ArgumentParser(description="""
Process a batch of .glsl files. Minify and export them to C++ strings.

Performs the following transformations:
    * Strip comments.
    * Strip whitespace.
    * Strip unused #defines.
    * Rename stpq and rgba swizzles to xyzw.
    * Rename variables.
        - No new name begins with the '_' character, so internal code can begin names with '_'
          without fear of renaming collisions.
        - GLSL keywords and builtins are not renamed.
        - Tokens beginning with '@' have their new name exported to a header file.
        - Tokens beginning with '$' are not renamed, with the exception of removing the leading '$'.

"file.glsl" gets exported to:
    * "outdir/file.exports.h", with #defines for the rewritten names of each identifier that began
      with '@' in the original shader.
    * "outdir/file.glsl.cpp", with a global `const char file_glsl[]` in the rive::glsl
      namespace that contains the minified shader code. This variable is intentionally declared as a
      global in order to generate a link error if the user includes the string more than once in
      the build process.
    * "outdir/file.minified.glsl" for offline compiling, with all variables renamed except for
      exported #defines names (since the offline compiling process will set those defines).
""")
parser.add_argument("files", type=str, nargs="+", help="a list of glsl files")
parser.add_argument("-o", "--outdir", required=True,
                    help="OUTPUT directory to store the header files")
parser.add_argument("-H", "--human-readable", action='store_true',
                    help="don't rename or strip out comments or whitespace")
parser.add_argument("-p", "--ply-path", type=str, help="path to ply module")
parser.add_argument("-m", "--msvc", action="store_true", help="set this to generate MSVC-compatible headers")

args = parser.parse_args()

if args.ply_path:
    # --ply-path was specified, so add it to the sys path so we can locate the module.
    # (if it was not specified we'll assume that it's already reachable via the path)

    # Convert posix path to windows
    convertedPath = args.ply_path
    if sys.platform.startswith('win32') and args.ply_path[:2] == '/c':
        convertedPath = 'C:\\' + args.ply_path[2:]
        print('Using ply path:' + convertedPath)

    sys.path.append(convertedPath)

import ply.lex as lex

# tokens used by PLY to run lexical analysis on our glsl files.
tokens = [
    "DEFINE",
    "IFDEF",
    "DEFINED_ID",
    "TOKEN_PASTE",
    "DIRECTIVE",
    "LINE_COMMENT",
    "BLOCK_COMMENT",
    "WHITESPACE",
    "OP",
    "FLOAT",
    "HEX",
    "INT",
    "ID",
    "UNKNOWN",
]

# tracks which exported identifiers (identifiers whose @name begins with '@') are used as switches
# inside an #ifdef, #if defined(), etc.
exported_switches = set()

# counts the number of times each ID is seen, to prioritize which IDs get the shortest names
all_id_counts = defaultdict(int);
all_id_reference_counts = defaultdict(int);
def parse_id(name, exports, *, is_reference):
    all_id_counts[name] += 1
    if is_reference:
        all_id_reference_counts[name] += 1
    # identifiers that begin with '@' get exported to C++ through #defines.
    if name[0] == '@':
        exports.add(name)

# lexing functions used by PLY.
def t_DEFINE(tok):
    r"\#[ \t]*define[ \t]+(?P<id>[\@\$]?[A-Za-z_][A-Za-z0-9_]*)(?P<arglist>\((\n|[^\)])*\))?(?P<val>(((\\\n|.)(?!\/[\/\*]))*))?"
    tok.define_id = re.match(t_DEFINE.__doc__, tok.value)['id']
    arglist = re.match(t_DEFINE.__doc__, tok.value)['arglist']
    tok.define_arglist = Minifier(arglist, "", tok.lexer.exports) if arglist else None
    val = re.match(t_DEFINE.__doc__, tok.value)['val']
    tok.define_val = Minifier(val, "", tok.lexer.exports) if val else None
    parse_id(tok.define_id, tok.lexer.exports, is_reference=False)
    tok.lexer.lineno += tok.value.count('\n')
    return tok

def t_IFDEF(tok):
    r"\#[ \t]*(?P<tag>ifn?def)[ \t]+(?P<ifdef_id>[\@\$]?[A-Za-z_][A-Za-z0-9_]*)"
    tok.ifdef_tag = re.match(t_IFDEF.__doc__, tok.value)['tag']
    tok.ifdef_id = re.match(t_IFDEF.__doc__, tok.value)['ifdef_id']
    if tok.ifdef_id[0] == '@':
        exported_switches.add(tok.ifdef_id)
    parse_id(tok.ifdef_id, tok.lexer.exports, is_reference=True)
    return tok

def t_DEFINED_ID(tok):
    r"defined\((?P<defined_id>[\@\$]?[A-Za-z_][A-Za-z0-9_]*)\)"
    tok.defined_id = re.match(t_DEFINED_ID.__doc__, tok.value)['defined_id']
    if tok.defined_id[0] == '@':
        exported_switches.add(tok.defined_id)
    parse_id(tok.defined_id, tok.lexer.exports, is_reference=True)
    return tok

def t_TOKEN_PASTE(tok):
    r"\#\#"
    return tok

def t_DIRECTIVE(tok):
    r"\#[ \t]*(?P<val>(((\\\n|.)(?!\/[\/\*]))*))"
    val = re.match(t_DIRECTIVE.__doc__, tok.value)['val']
    tok.directive_val = Minifier(val, "", tok.lexer.exports) if val else None
    tok.lexer.lineno += tok.value.count('\n')
    return tok

def t_LINE_COMMENT(tok):
    r"//(\\\n|.)*"
    tok.lexer.lineno += tok.value.count('\n')
    return tok

def t_BLOCK_COMMENT(tok):
    r"\/\*(\*(?!\/)|[^*])*\*\/"
    tok.lexer.lineno += tok.value.count('\n')
    return tok

def t_WHITESPACE(tok):
    r"(\s|\\\r?\n)+"
    tok.lexer.lineno += tok.value.count('\n')
    return tok

def t_OP(tok):
    r"[~!%^&\*\(\)\-=+\/\[\]{}\?:\<\>\.\,|;]"
    return tok

def t_FLOAT(tok):
    r"([0-9]*\.[0-9]+|[0-9]+\.)([eE][+\-]?[0-9]+)?|([0-9]+[eE][+\-]?[0-9]+)"
    return tok

def t_HEX(tok):
    r"0x[0-9a-fA-F]+u?"
    return tok

def t_INT(tok):
    r"[0-9]+u?"
    return tok

def t_ID(tok):
    r"[\@\$]?[A-Za-z_][A-Za-z0-9_]*"
    parse_id(tok.value, tok.lexer.exports, is_reference=True)
    return tok

def t_UNKNOWN(tok):
    r"."
    return tok

def t_error(tok):
    raise Exception("Illegal character '%s' at line %d" % (tok.value[0], tok.lexer.lineno))

# identifier names that cannot be renamed
glsl_reserved = {
    'EmitStreamVertex', 'EmitVertex', 'EndPrimitive', 'EndStreamPrimitive',
    '__VERSION__', '__pixel_localEXT', '__pixel_local_inEXT',
    '__pixel_local_outEXT', 'abs', 'acos', 'acosh', 'all', 'allInvocations',
    'allInvocationsEqual', 'any', 'anyInvocation', 'asin', 'asinh', 'atan',
    'atanh', 'atomicAdd', 'atomicAnd', 'atomicCompSwap', 'atomicCounter',
    'atomicCounterAdd', 'atomicCounterAnd', 'atomicCounterCompSwap',
    'atomicCounterDecrement', 'atomicCounterExchange', 'atomicCounterIncrement',
    'atomicCounterMax', 'atomicCounterMin', 'atomicCounterOr',
    'atomicCounterSubtract', 'atomicCounterXor', 'atomicExchange', 'atomicMax',
    'atomicMin', 'atomicOr', 'atomicXor', 'barrier',
    'beginFragmentShaderOrderingINTEL', 'beginInvocationInterlockARB',
    'beginInvocationInterlockNV', 'binding', 'bitCount', 'bitfieldExtract',
    'bitfieldInsert', 'bitfieldReverse', 'blend_support_all_equations',
    'blend_support_colorburn', 'blend_support_colordodge',
    'blend_support_darken', 'blend_support_difference',
    'blend_support_exclusion', 'blend_support_hardlight',
    'blend_support_lighten', 'blend_support_multiply', 'blend_support_overlay',
    'blend_support_screen', 'blend_support_softlight', 'bool', 'break',
    'buffer', 'bvec2', 'bvec3', 'bvec4', 'case', 'ceil', 'centroid', 'clamp',
    'coherent', 'const', 'constant_id', 'continue', 'cos', 'cosh', 'cross',
    'dFdx', 'dFdxCoarse', 'dFdxFine', 'dFdy', 'dFdyCoarse', 'dFdyFine',
    'default', 'defined', 'degrees', 'determinant', 'discard', 'distance', 'do',
    'dot', 'elif', 'else', 'enable', 'endInvocationInterlockARB',
    'endInvocationInterlockNV', 'endif', 'equal', 'exp', 'exp2', 'extension',
    'faceforward', 'false', 'findLSB', 'findMSB', 'flat', 'float',
    'floatBitsToInt', 'floatBitsToUint', 'floor', 'fma', 'for', 'fract',
    'frexp', 'ftransform', 'fwidth', 'fwidthCoarse', 'fwidthFine',
    'greaterThan', 'greaterThanEqual', 'groupMemoryBarrier', 'highp', 'if',
    'iimage2D', 'image2D', 'imageAtomicAdd', 'imageAtomicAnd',
    'imageAtomicCompSwap', 'imageAtomicExchange', 'imageAtomicMax',
    'imageAtomicMin', 'imageAtomicOr', 'imageAtomicXor', 'imageLoad',
    'imageSamples', 'imageSize', 'imageStore', 'imulExtended', 'in', 'inout',
    'input_attachment_index', 'int', 'intBitsToFloat', 'interpolateAtCentroid',
    'interpolateAtOffset', 'interpolateAtSample', 'invariant', 'inverse',
    'inversesqrt', 'isampler2D', 'isampler2DArray', 'isampler3D',
    'isamplerCube', 'isinf', 'isnan', 'ivec2', 'ivec3', 'ivec4', 'layout',
    'ldexp', 'length', 'lessThan', 'lessThanEqual', 'location', 'log', 'log2',
    'lowp', 'main', 'mat2', 'mat2x2', 'mat2x3', 'mat2x4', 'mat3', 'mat3x2',
    'mat3x3', 'mat3x4', 'mat4', 'mat4x2', 'mat4x3', 'mat4x4', 'matrixCompMult',
    'max', 'mediump', 'memoryBarrier', 'memoryBarrierAtomicCounter',
    'memoryBarrierBuffer', 'memoryBarrierImage', 'memoryBarrierShared', 'min',
    'mix', 'mod', 'modf', 'noise1', 'noise2', 'noise3', 'noise4',
    'noperspective', 'normalize', 'not', 'notEqual', 'out', 'outerProduct',
    'packDouble2x32', 'packHalf2x16', 'packSnorm2x16', 'packSnorm4x8',
    'packUnorm2x16', 'packUnorm4x8', 'pixelLocalLoadANGLE',
    'pixelLocalStoreANGLE', 'pow', 'pragma', 'precision', 'push_constant',
    'r16f', 'r32f', 'r32i', 'r32ui', 'radians', 'readonly', 'reflect',
    'refract', 'require', 'return', 'rg16f', 'rgb10_a2', 'rgb_2_yuv', 'rgba8',
    'rgba8i', 'rgba8ui', 'round', 'roundEven', 'sampler', 'sampler2D',
    'sampler2DArray', 'sampler2DArrayShadow', 'sampler2DShadow', 'sampler3D',
    'samplerCube', 'samplerCubeShadow', 'set', 'shadow1D', 'shadow1DLod',
    'shadow1DProj', 'shadow1DProjLod', 'shadow2D', 'shadow2DEXT', 'shadow2DLod',
    'shadow2DProj', 'shadow2DProjEXT', 'shadow2DProjLod', 'sign', 'sin', 'sinh',
    'smooth', 'smoothstep', 'sqrt', 'std140', 'std430', 'step', 'struct',
    'subpassInput', 'subpassInputMS', 'subpassLoad', 'switch', 'tan', 'tanh',
    'texelFetch', 'texelFetchOffset', 'texture', 'texture1D', 'texture1DLod',
    'texture1DProj', 'texture1DProjLod', 'texture2D', 'texture2DGradEXT',
    'texture2DLod', 'texture2DLodEXT', 'texture2DProj', 'texture2DProjGradEXT',
    'texture2DProjLod', 'texture2DProjLodEXT', 'texture2DRect',
    'texture2DRectProj', 'texture3D', 'texture3DLod', 'texture3DProj',
    'texture3DProjLod', 'textureCube', 'textureCubeGradEXT', 'textureCubeLod',
    'textureCubeLodEXT', 'textureGather', 'textureGatherOffset',
    'textureGatherOffsets', 'textureGrad', 'textureGradOffset', 'textureLod',
    'textureLodOffset', 'textureOffset', 'textureProj', 'textureProjGrad',
    'textureProjGradOffset', 'textureProjLod', 'textureProjLodOffset',
    'textureProjOffset', 'textureQueryLevels', 'textureQueryLod',
    'textureSamples', 'textureSize', 'textureVideoWEBGL', 'transpose', 'true',
    'trunc', 'uaddCarry', 'uimage2D', 'uint', 'uintBitsToFloat', 'umulExtended',
    'undef', 'uniform', 'unpackDouble2x32', 'unpackHalf2x16', 'unpackSnorm2x16',
    'unpackSnorm4x8', 'unpackUnorm2x16', 'unpackUnorm4x8', 'usampler2D',
    'usampler2DArray', 'usampler3D', 'usamplerCube', 'usubBorrow',
    'usubpassInput', 'utexture2D', 'uvec2', 'uvec3', 'uvec4', 'vec2', 'vec3',
    'vec4', 'void', 'volatile', 'while', 'yuv_2_rgb'
}

# rgba and stpq get rewritten to xyzw, so we only need to check xyzw here. This way we can keep
# renaming to names like, e.g., "rg".
xyzw_pattern = re.compile(r"^[xyzw]{1,4}$")

# HLSL registers base names can't be overwritten by macro arguments if token pasting (e.g. t##IDX).
hlsl_register_base_names = ['t', 's', 'u', 'b']

# HLSL registers (e.g., t0, u1) can't be overwritten by a #define.
hlsl_register_pattern = re.compile(r"^[tsub]\d+$")

# can we rename to or from 'name'?
def is_reserved_keyword(name):
    return name in glsl_reserved\
           or xyzw_pattern.match(name)\
           or name in hlsl_register_base_names\
           or hlsl_register_pattern.match(name)\
           or name.startswith("$")\
           or name.startswith("gl_")\
           or name.startswith("GL_")\
           or name.startswith("__pixel_local")\
           or name.endswith("ANGLE")

def remove_leading_annotation(name):
    if name[0] == '@':
        # A leading '@' indicates identifier names that should be exported. Rename '@my_var' to
        # '_EXPORTED_my_var' to enforce that '@my_var' and 'my_var' are not interchangeable.
        return 'EXPORTED_' + name[1:]
    if name[0] == '$':
        # A leading '$' indicates identifier names that should not be renamed.
        return name[1:]
    return name

# Generates new identifier names to rewrite our variables.
class NameGenerator:
    def __init__(self, first_letter_chars, additional_letter_chars):
        self.first_letter_chars = first_letter_chars
        self.additional_letter_chars = additional_letter_chars
        self.name_index = 0

    def next_name(self):
        i = self.name_index
        # Generate the first character from 'self.first_letter_chars'
        name = self.first_letter_chars[i % len(self.first_letter_chars)]
        i = i // len(self.first_letter_chars)
        while i > 0:
            # Generate the remaining characters from 'self.additional_letter_chars'
            name += self.additional_letter_chars[i % len(self.additional_letter_chars)]
            i = i // len(self.additional_letter_chars)
        self.name_index = self.name_index + 1
        return name

# Exported variables only use upper case letters in their names. HLSL semantics are not case
# sensitive and may also assign special meaning to numbers.
upper_case_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
upper_case_name_generator = NameGenerator(upper_case_chars, upper_case_chars + "_")

# Don't begin new names with the the '_' character. Internal code can begin names with '_' without
# fear of renaming collisions.
lower_and_upper_chars = "abcdefghijklmnopqrstuvwxyz" + upper_case_chars
general_name_generator = NameGenerator(lower_and_upper_chars, "_0123456789" + lower_and_upper_chars)

used_new_names = set()

def generate_new_name(*, force_upper_case):
    name_generator = upper_case_name_generator if force_upper_case else general_name_generator
    while True:
        name = name_generator.next_name()
        if not is_reserved_keyword(name) and not name in used_new_names:
            used_new_names.add(name)
            return name

# mapping from original identifiers to new names.
new_names = {}
def generate_new_names():
    for name,count in sorted(all_id_counts.items(), key=lambda x:x[1], reverse=True):
        new_name = (remove_leading_annotation(name)
                    if args.human_readable or is_reserved_keyword(name)
                    # HLSL semantics are not case sensitive and can assign special meaning to
                    # numbers. Make all exported names upper case with no numbers.
                    else generate_new_name(force_upper_case=name[0] == '@'))
        new_names[name] = new_name

# used to rewrite rgba and stpq swizzles to xyzw.
rgba_stpq_pattern = re.compile(r"^([rgba]{1,4}|[stpq]{1,4})$")
rgba_stpq_remap = {'r':'x', 'g':'y', 'b':'z', 'a':'w',
                   's':'x', 't':'y', 'p':'z', 'q':'w',}


# minifies a single GLSL file.
class Minifier:
    def __init__(self, code, basename, exports=set()):
        # parse tokens.
        lexer = lex.lex()
        lexer.exports = exports
        lexer.input(code)
        self.tokens = [tok for tok in lexer];
        self.exports = exports
        self.basename = basename


    # Strips unneeded code from the tokens. Called after all Minifiers have been parsed.
    def strip_tokens(self):
        assert(not args.human_readable)

        # strip comments.
        self.tokens = \
            [tok for tok in self.tokens if "COMMENT" not in tok.type]

        # strip unused defines.
        self.tokens = [tok for tok in self.tokens if tok.type != "DEFINE"\
                                                  or all_id_reference_counts[tok.define_id] > 0]

        # merge whitespace.
        unmerged,self.tokens = self.tokens,[]
        for tok in unmerged:
            if tok.type == "DEFINE":
                if tok.define_arglist != None:
                    tok.define_arglist.strip_tokens()
                if tok.define_val != None:
                    tok.define_val.strip_tokens()
            if tok.type == "DIRECTIVE":
                if tok.directive_val != None:
                    tok.directive_val.strip_tokens()
            if (tok.type == "WHITESPACE"
                and len(self.tokens) > 0
                and self.tokens[-1].type == "WHITESPACE"):
                self.tokens[-1].value += tok.value
            else:
                self.tokens.append(tok)


    # generates rewritten glsl from our tokens.
    def emit_tokens_to_rewritten_glsl(self, out, *, preserve_exported_switches, calling_token_type:str=None):
        # stand-in for a null token.
        lasttoken = lambda : None
        lasttoken.type = ""
        lasttoken.value = ""

        lasttoken_needs_whitespace = False
        is_newline = True

        for tok in self.tokens:
            if tok.type == "WHITESPACE":
                if args.human_readable:
                    out.write(tok.value)
                    is_newline = tok.value[-1] == '\n'
                    lasttoken_needs_whitespace = False
                continue

            is_directive = tok.type in ["DEFINE", "IFDEF", "DIRECTIVE"]
            needs_whitespace = tok.type in ["FLOAT", "INT", "HEX", "ID", "DEFINED_ID"]
            # Adding this calling_token_type != 'DEFINE' prevents us from adding a new line to stringify macros
            if is_directive and not is_newline and calling_token_type != 'DEFINE':
                out.write('\n')
            elif needs_whitespace and lasttoken_needs_whitespace:
                out.write(' ')
            elif tok.type == "ID" and lasttoken.type == "OP" and lasttoken.value == ")":
                # Mesa can reject minified GLSL macro calls when the next
                # identifier is directly adjacent, e.g. OUT(float2)foo.
                out.write(' ')

            # is_newline will be false once we output the token (unless this value otherwise gets
            # updated).
            is_newline = False

            if tok.type == "ID":
                if (rgba_stpq_pattern.match(tok.value)
                    and lasttoken.type == "OP"
                    and lasttoken.value == "."):
                    # convert rgba and stpq to xyzw.
                    out.write(''.join([rgba_stpq_remap[ch] for ch in tok.value]))
                else:
                    self.write_identifier(out, tok.value, preserve_exported_switches)

            elif tok.type == "DEFINE":
                out.write("#define ")
                self.write_identifier(out, tok.define_id, preserve_exported_switches)
                if tok.define_arglist != None:
                    is_newline = tok.define_arglist.emit_tokens_to_rewritten_glsl(\
                        out,\
                        preserve_exported_switches=preserve_exported_switches,\
                        calling_token_type=tok.type)
                    assert(not is_newline)
                if tok.define_val != None:
                    out.write(' ')
                    is_newline = tok.define_val.emit_tokens_to_rewritten_glsl(\
                        out,\
                        preserve_exported_switches=preserve_exported_switches,\
                        calling_token_type=tok.type)

            elif tok.type == "IFDEF":
                out.write('#')
                out.write(tok.ifdef_tag)
                out.write(' ')
                self.write_identifier(out, tok.ifdef_id, preserve_exported_switches)

            elif tok.type == "DEFINED_ID":
                out.write('defined(')
                self.write_identifier(out, tok.defined_id, preserve_exported_switches)
                out.write(')')

            elif tok.type == "DIRECTIVE":
                out.write("#")
                if tok.directive_val != None:
                    is_newline = tok.directive_val.emit_tokens_to_rewritten_glsl(\
                        out,\
                        preserve_exported_switches=preserve_exported_switches,\
                        calling_token_type=tok.type)

            else:
                out.write(tok.value)

            # Since we preserve whitespace in 'human_readable' mode, the newline after a
            # preprocessor directive will happen for us automatically unless 'human_readable' is
            # false.
            if not args.human_readable and is_directive and not is_newline:
                out.write('\n')
                is_newline = True

            lasttoken = tok
            lasttoken_needs_whitespace = needs_whitespace

        return is_newline


    def write_identifier(self, out, identifier, preserve_exported_switches):
        if preserve_exported_switches and identifier in exported_switches:
            assert(identifier[0] == '@')
            out.write(identifier[1:])
        else:
            out.write(new_names[identifier])


    def write_exports(self, outdir):
        output_path = os.path.join(outdir, f"{self.basename}.exports.h")
        print(f"Exporting {output_path} <- {self.basename}")
        out = open(output_path, "w", newline='\n')
        out.write('#pragma once\n\n')
        for exp in sorted(self.exports):
            out.write('#define GLSL_%s "%s"\n' % (exp[1:], new_names[exp]))
            out.write('#define GLSL_%s_raw %s\n' % (exp[1:], new_names[exp]))
        out.close()


    def write_embedded_glsl(self, outdir):
        output_path = os.path.join(outdir, self.basename + ".hpp")
        print("Embedding %s <- %s" % (output_path, self.basename))
        out = open(output_path, "w", newline='\n')
        out.write("#pragma once\n\n")

        out.write(f'#include "{self.basename}.exports.h"\n\n')

        # emit shader code.
        root, ext = os.path.splitext(self.basename)
        cpp_name = root
        if ext != '.glsl':
            cpp_name = f"{root}_{ext[1:]}"
        out.write("namespace rive {\n")
        out.write("namespace gpu {\n")
        out.write("namespace glsl {\n")
        if args.msvc:
            # MSVC cannot compile raw shaders as strings because of an internal
            # string length limit. There is, however, no limit on arrays so
            # instead write it out as an array of individual characters.
            out.write(f'const char {cpp_name}[] = {{\n   ')

            codeIO = io.StringIO()
            self.emit_tokens_to_rewritten_glsl(codeIO, preserve_exported_switches=False)

            out_ch_count = 0
            for ch in codeIO.getvalue():
                # use `repr` to escape the characters (but we need to handle single
                # quote manually, since it will represent that as "'" - which will
                # definitely not compile)

                out.write(f" {repr(ch)},") if ch != "'" else out.write(" '\\'',")
                out_ch_count = out_ch_count + 1
                CHAR_COUNT_PER_LINE = 12
                if (out_ch_count % CHAR_COUNT_PER_LINE) == 0:
                    out.write('\n   ')
            # Null-terminate so the array is a valid C-string when passed to
            # APIs like ostream::operator<<(const char*), which read until '\0'.
            out.write(" '\\0'\n};\n")
        else:
            # For non-MSVC outputs just output as a raw string
            out.write(f'const char {cpp_name}[] = R"===(')

            is_newline = self.emit_tokens_to_rewritten_glsl(out, preserve_exported_switches=False)
            if not is_newline:
                out.write('\n')

            out.write(')===";\n')
        out.write("} // namespace glsl\n")
        out.write("} // namespace gpu\n")
        out.write("} // namespace rive")
        out.close()

    def write_offline_glsl(self, outdir):
        root, ext = os.path.splitext(self.basename)
        output_path = os.path.join(outdir, f"{root}.minified{ext}")
        print(f"Minifying f{output_path} <- {self.basename}")
        out = open(output_path, "w", newline='\n')
        self.emit_tokens_to_rewritten_glsl(out, preserve_exported_switches=True)
        out.close()


# parse all GLSL files before renaming. This keeps the renaming consistent across files.
minifiers = [Minifier(open(f).read(), os.path.basename(f)) for f in args.files]
generate_new_names()

# minify all GLSL files.
if not os.path.exists(args.outdir):
   os.makedirs(args.outdir)
for m in minifiers:
    if not args.human_readable:
        m.strip_tokens()
    m.write_exports(args.outdir)
    m.write_embedded_glsl(args.outdir)
    m.write_offline_glsl(args.outdir)
