/* Tests for libfossil/th1ish delta generation and application... */
scope {/* just to get some UTF8 in here for diff validation */
    // If any of these assertions fail then this file is not UTF8-encoded
    assert "®" === [["®".charAt 0 true].toUtf8Char]
    assert "®" === [["©®".charAt 1 true].toUtf8Char]
    assert "®" === "©®".charAt(1,true).toUtf8Char()
    assert "ä" === "äbä".substr(0,1)
    assert "©" === "äb©®ä".substr(2,1)
    assert "©®" === "äb©®ä".substr(2,2)
}

scope {

    // The base content we want to delta against...
    const inFile = __FILE
    const inSize = [Fossil.file.size inFile]
    const b = [api.Buffer inSize+1]
    [b.readFile inFile]
    [print "Input file: " inFile ", size=" inSize]

    const bStr = [b.toString]

    // Make a modified copy of the original...
    //const c = [clone b] //[api.Buffer inSize+1]
    print(b.length())
    var c = api.Buffer(inSize+1)
    assert 0 === c.length()
    c.append(b)
    //print(inSize,c.capacity(),c.length(),b.capacity(),b.length())
    assert c.length() === b.length()
    assert c === b // special case for buffer comparison compares underlying memory
    if(0){
        assert catch{
            c.append('hi')
            assert c === b // will fail
        }
    }
    
    //[c.append b] // bug (in th1ish): this is appending very wrongly
    //[c.append [b.toString]] // but this is very inefficient

    // Make some changes to it...
    const corruptOffset = 250/**
        try to keep this in the middle of a UTF8 char, just to break
        things. */
    [c.fill 42 corruptOffset 20] 
    assert 42 === [c.byteAt corruptOffset+3]
    const bLen = [b.length]
    [c.fill 42 bLen/2 30]
    assert 42 === [c.byteAt bLen/2]

    const cStr = [c.toString]
    //[print "<<<<<"[cStr]">>>>>"]

    /**
        If corruptOffset is set as commented above then
        then 'c', cStr, and the applied delta will contain an
        invalid (or unintended) UTF8 char at byte offset
        (corruptOffset-1).
    */

    // Create a delta...
    const d = [Fossil.delta.create b c]
    const dStr = [d.toString]
    //[print 'Delta: ' dStr]
    [print "Delta's applied length=" [Fossil.delta.appliedLength d]]

    // Apply the delta to the original...
    const a = [Fossil.delta.apply b d], aStr = [a.toString]
    //[print "Applied delta" dStr]

    // And assure that the original meets expectations...
    assert aStr === cStr // Uses memcmp() instead of UTF8-validating compare
    [print "Delta playback/comparison worked."]

    // But note that applying a delta will fail if fossil
    // detects any foul play...
    assert 'FSL_RC_CHECKSUM_MISMATCH' === $Fossil.rcString catch{
        // Corrupt the delta and try to apply it:
        [d.byteAt 20 3]
        [Fossil.delta.apply b d]
    }.code
    print("Correctly failed to apply corrupted delta.")

    0 && [print aStr] // remember: invalid UTF8
}

