Import('env')
Import('VERSION')
Import('create_uninstall_target')

import os
from pathlib import Path

from rm_build_support import ConfigHeaderBuilder, EmbedPayloadBuilder

ENV_KEYS = (
    # libraries
    'HAVE_LIBELF', 'HAVE_GIO_UNIX', 'HAVE_BLKID', 'HAVE_LIBINTL',
    # headers
    'HAVE_LINUX_LIMITS', 'HAVE_LINUX_FS_H', 'HAVE_BTRFS_H', 'HAVE_SYSMACROS_H',
    # syscalls / filesystem features
    'HAVE_FIEMAP', 'HAVE_XATTR', 'HAVE_LXATTR', 'HAVE_EXTATTR',
    'HAVE_POSIX_FADVISE', 'HAVE_SYSBLOCK', 'HAVE_UNAME',
    # cpu extensions
    'HAVE_MM_CRC32_U64', 'HAVE_BUILTIN_CPU_SUPPORTS',
    # language features
    'HAVE_C23_EMBED',
)

# XXX: remove this when we fully switch to C23+ only
MAYBE_EMBEDED_FORMATTERS = (
    ('formats/py.c', 'formats/py.py'),
    ('formats/sh.c', 'formats/sh.sh'),
)
FORMATTER_NAMES = {os.path.basename(src) for src, _ in MAYBE_EMBEDED_FORMATTERS}

CONFIG_VALUES = {
    **{key: env[key] for key in ENV_KEYS},
    'INSTALL_PREFIX': env['PREFIX'],
    'VERSION': str(VERSION),
    'VERSION_MAJOR': VERSION.major,
    'VERSION_MINOR': VERSION.minor,
    'VERSION_PATCH': VERSION.patch,
    'VERSION_NAME': VERSION.name,
    'VERSION_GIT_REV': env['gitrev'] or 'unknown',
    'VERSION_FULL': VERSION.with_rev(env['gitrev']),
}


env.Append(BUILDERS={
    'ConfigHeader': ConfigHeaderBuilder,
    'EmbedPayload': EmbedPayloadBuilder,
})

config = env.ConfigHeader('config.h', ['config.h.in', env.Value(CONFIG_VALUES)])

payloads = []
if not env['HAVE_C23_EMBED']:
    payloads = [env.EmbedPayload(f'{payload}.c.inc', payload)
                for _, payload in MAYBE_EMBEDED_FORMATTERS]

# XXX: remove this when we fully switch to C23+ only
formatter_env = env
if env['HAVE_C23_EMBED']:
    formatter_env = env.Clone(CCFLAGS=[
        flag for flag in env['CCFLAGS'] if not str(flag).startswith('-std=')
    ] + ['-std=c23'])

formatters = []
for source, payload in MAYBE_EMBEDED_FORMATTERS:
    obj = formatter_env.Object(source)
    # XXX: to be removed when/if https://github.com/SCons/scons/pull/4889 is merged
    env.Depends(obj, payload)
    formatters.append(obj)

# Listed unconditionally so that 'scons -c' also clears old c.inc files on a new compiler
env.Clean(formatters, [f'{payload}.c.inc' for _, payload in MAYBE_EMBEDED_FORMATTERS])

checksums = SConscript('checksums/SConscript', exports='env')

library = env.Library(
    '../rmlint',
    Glob('*.c') +
    checksums +
    formatters +
    [node for node in Glob('formats/*.c') if node.name not in FORMATTER_NAMES] +
    Glob('fts/*.c')
)

headers = Glob('*.h')
env.Depends(library, [config, *payloads])

libdir = env['staged_prefix'] / env['LIBDIR']
includedir = env['staged_prefix'] / 'include' / 'rmlint'

if 'install-lib' in COMMAND_LINE_TARGETS:
    env.Alias('install-lib', env.Install(str(libdir), [library]))
    for header in headers:
        env.Alias('install-lib', env.Install(str(includedir), [header]))

if 'uninstall-lib' in COMMAND_LINE_TARGETS:
    create_uninstall_target(env, libdir / Path(str(library[0])).name, target='uninstall-lib')

    for header in headers:
        create_uninstall_target(env, includedir / str(header))

Return('library')
