#!/usr/bin/env python3
"""Save game resource paths and keep Xcode's derived data on the game's drive.

Called by build_ipa.sh after xcodegen. No game files are copied here.
"""
import getpass
import os
from pathlib import Path
import plistlib
import shlex
import sys


def workspace_settings(workspace, derived):
    settings = Path(workspace) / 'xcuserdata' / f'{os.environ.get("USER") or getpass.getuser()}.xcuserdatad/WorkspaceSettings.xcsettings'
    values = plistlib.loads(settings.read_bytes()) if settings.exists() else {}
    # A workspace-wide custom product path overrides the per-game target paths.
    # Keep only the cache preference here; the targets own their product/intermediate paths.
    values.update(BuildLocationStyle='UseAppPreferences', DerivedDataLocationStyle='AbsolutePath',
                  DerivedDataCustomLocation=str(Path(derived).resolve()))
    for key in ('CustomBuildLocationType', 'CustomBuildProductsPath', 'CustomBuildIntermediatesPath'):
        values.pop(key, None)
    settings.parent.mkdir(parents=True, exist_ok=True)
    settings.write_bytes(plistlib.dumps(values))


def main():
    ios, romfs, marker, shaders, msldir, aoc, derived, chain_h, *rest = sys.argv[1:]
    pso = rest[0] if rest else ''   # the pipeline archive made offline (build_ipa.sh, dm/gfx/tools/pso_offline.py), or none
    programs = rest[1:]   # a game of several programs: the table of each one's files (build_ipa.sh)
    ios = Path(ios)
    paths = {
        'DM_RESOURCE_ROMFS': str(Path(romfs).resolve()),
        'DM_RESOURCE_MARKER': marker,
        'DM_RESOURCE_SHADERS': str(Path(shaders).resolve()),
        'DM_RESOURCE_MSLDIR': msldir,
        'DM_RESOURCE_AOC': str(Path(aoc).resolve()) if aoc and Path(aoc).is_dir() else '',
        'DM_RESOURCE_CHAIN_H': str(Path(chain_h).resolve()),   # dm/gfx/nvn/dmsh_chain.h, which the host is compiled with (one chain version for every game)
        'DM_RESOURCE_PSO': str(Path(pso).resolve()) if pso and Path(pso).is_dir() else '',   # → <App>/pso, which the app hands the host as DM_PSO_BUNDLE
        # what the identity line of a RomFS image names (stage_resources.sh with DM_COPY_ROMFS=NO writes <App>/romfs.id): title ID, display version, package version
        'DM_RESOURCE_TITLE': os.environ.get('GAME', ''),
        'DM_RESOURCE_VERSION': os.environ.get('DM_APP_VERSION', ''),
        'DM_RESOURCE_BUILD': os.environ.get('DM_RESOURCE_BUILD', ''),
        'DM_RESOURCE_PROGRAMS': str(Path(ios, programs[0]).resolve()) if programs else '',   # with it, the RomFS and shaders above are program 0's and stage_resources.sh takes the table
    }
    (ios / 'Gen/resources.env').write_text(
        '# Generated by build_ipa.sh; regenerate when the game or its drive changes.\n'
        + ''.join(f'{k}={shlex.quote(v)}\n' for k, v in paths.items()), encoding='utf-8')
    # Target build settings also pin products/intermediates here: command-line Xcode can
    # ignore the per-user workspace preference, and the app's resources are very large.
    with (ios / 'Gen/dm.xcconfig').open('a', encoding='utf-8') as config:
        config.write(f'DM_XCODE_OUTPUT_ROOT = {Path(derived).resolve()}\n')
    workspace_settings(ios / 'DmIOS.xcodeproj/project.xcworkspace', derived)


if __name__ == '__main__':
    main()
