# This file is part of the open-lmake distribution (git@github.com:cesar-douady/open-lmake.git)
# Copyright (c) 2023-2025 Doliam
# This program is free software: you can redistribute/modify under the terms of the GPL-v3 (https://www.gnu.org/licenses/gpl-3.0.html).
# This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

if __name__!='__main__' :

    import lmake
    from lmake.rules import Rule

    lmake.config.trace.channels = ('cache',)

    lmake.manifest = (
        'Lmakefile.py'
    ,   'step.py'
    ,   'hello'
    ,   'hello+auto1.hide.ref'
    ,   'mkdir.dut.ref'
    )

    from step import z_lvl

    lmake.config.caches.my_cache = {
        'tag'  : 'dir'
    ,   'dir'  : lmake.repo_root+'/CACHE'
    }

    class Auto(Rule) :
        target = r'auto{:\d}'
        cache  = 'my_cache'
        cmd    = "echo '#auto'"

    class Hide(Rule) :
        target    = r'{File:.*}.hide'
        stderr_ok = True
        cache     = 'my_cache'
        cmd       = 'cat {File} || :'

    class Cat(Rule) :
        prio = 1
        stems = {
            'File1' : r'.*'
        ,   'File2' : r'.*'
        }
        target = '{File1}+{File2}'
        deps = {
            'FIRST'  : '{File1}'
        ,   'SECOND' : '{File2}'
        }
        cache       = 'my_cache'
        compression = z_lvl
        cmd         = 'cat {FIRST} {SECOND}'

    class MkDir(Rule):
        target      = 'mkdir.dut'
        targets     = { 'OUT' : r'mkdir.dir/{*:.*}' }
        cache       = 'my_cache'
        compression = z_lvl
        cmd = '''
            dir={OUT('v1')}
            mkdir -p $dir
            > $dir/res
            echo mkdir
        '''

    class Ok(Rule) :
        target = r'{File:.*}.ok'
        deps = {
            'DUT' : '{File}'
        ,   'REF' : '{File}.ref'
        }
        cmd = 'diff {REF} {DUT}>&2'

else :

    import os
    import textwrap

    import ut

    for z_lvl in (0,5) :
        print(f'z_lvl={z_lvl}',file=open('step.py','w'))

        print('hello'       ,file=open('hello'               ,'w'))
        print('hello\n#auto',file=open('hello+auto1.hide.ref','w'))
        print('mkdir'       ,file=open('mkdir.dut.ref'       ,'w'))

        # cache my_cache must be writable by all users having access to the cache
        # use setfacl(1) with adequate rights in the default ACL, e.g. :
        # os.system('setfacl -m d:g::rw,d:o::r CACHE')
        os.makedirs('CACHE/LMAKE')
        os.chmod('CACHE'      ,0o775)
        os.chmod('CACHE/LMAKE',0o775)
        print(textwrap.dedent('''
            size = 1<<20
            perm = 'group'
        ''')[1:],file=open('CACHE/LMAKE/config.py','w'))

        ut.lmake( 'hello+auto1.hide.ok' , done=4 , may_rerun=1 , new=2 ) # check target is out of date
        ut.lmake( 'hello+auto1.hide.ok' , done=0                       ) # check target is up to date
        ut.lmake( 'mkdir.dut.ok'        , done=2 ,               new=1 ) # check everything is ok with dirs and empty files

        os.system(f'mkdir bck{z_lvl} ; mv LMAKE auto1 auto1.hide hello+auto1.hide bck{z_lvl}')
        os.system('find CACHE -type f -ls')

        assert os.system('rm -rf CACHE/auto1 ; ldir_cache_repair CACHE')==0

        print('hello2'       ,file=open('hello'               ,'w'))
        print('hello2\n#auto',file=open('hello+auto1.hide.ref','w'))
        ut.lmake( 'hello+auto1.hide.ok' , done=3 , hit_rerun=1 , hit_done=1 , unlinked=1                 , new=2 ) # check cache hit on common part (except auto1), and miss when we depend on hello
        ut.lmake( 'mkdir.dut.ok'        , done=1 , hit_rerun=1 , hit_done=1 , unlinked=1 , quarantined=1 , new=1 ) # check all is ok with dirs and empty files (mkdir.dut still exists and is unlinked)

        os.system(f'mkdir bck2{z_lvl} ; mv LMAKE CACHE *auto1* mkdir* bck2{z_lvl}')

    ut.lmake( 'hello+auto1.hide' , done=3 , may_rerun=1 , new=1 ) # check no crash with no cache