#!/usr/bin/env python3
#
# Test bitmap merges.
#
# Copyright (c) 2018 John Snow for Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# owner=jsnow@redhat.com

import iotests
from iotests import log

iotests.verify_image_format(supported_fmts=['generic'])
size = 64 * 1024 * 1024
granularity = 64 * 1024

patterns = [("0x5d", "0",         "64k"),
            ("0xd5", "1M",        "64k"),
            ("0xdc", "32M",       "64k"),
            ("0xcd", "0x3ff0000", "64k")]  # 64M - 64K

overwrite = [("0xab", "0",         "64k"), # Full overwrite
             ("0xad", "0x00f8000", "64k"), # Partial-left (1M-32K)
             ("0x1d", "0x2008000", "64k"), # Partial-right (32M+32K)
             ("0xea", "0x3fe0000", "64k")] # Adjacent-left (64M - 128K)

def query_bitmaps(vm):
    res = vm.qmp("query-block")
    return { "bitmaps": { device['device']: device.get('dirty-bitmaps', []) for
                          device in res['return'] } }

with iotests.FilePath('img') as img_path, \
     iotests.VM() as vm:

    log('--- Preparing image & VM ---\n')
    iotests.qemu_img_create('-f', iotests.imgfmt, img_path, str(size))
    vm.add_drive(img_path)
    vm.launch()

    log('\n--- Adding preliminary bitmaps A & B ---\n')
    vm.qmp_log("block-dirty-bitmap-add", node="drive0",
               name="bitmapA", granularity=granularity)
    vm.qmp_log("block-dirty-bitmap-add", node="drive0",
               name="bitmapB", granularity=granularity)

    # Dirties 4 clusters. count=262144
    log('\n--- Emulating writes ---\n')
    for p in patterns:
        cmd = "write -P%s %s %s" % p
        log(cmd)
        log(vm.hmp_qemu_io("drive0", cmd))

    log(query_bitmaps(vm), indent=2)

    log('\n--- Submitting & Aborting Transaction ---\n')
    vm.qmp_log("transaction", indent=2, actions=[
        { "type": "block-dirty-bitmap-disable",
          "data": { "node": "drive0", "name": "bitmapB" }},
        { "type": "block-dirty-bitmap-add",
          "data": { "node": "drive0", "name": "bitmapC",
                    "granularity": granularity }},
        { "type": "block-dirty-bitmap-clear",
          "data": { "node": "drive0", "name": "bitmapA" }},
        { "type": "abort", "data": {}}
    ])
    log(query_bitmaps(vm), indent=2)

    log('\n--- Disabling B & Adding C ---\n')
    vm.qmp_log("transaction", indent=2, actions=[
        { "type": "block-dirty-bitmap-disable",
          "data": { "node": "drive0", "name": "bitmapB" }},
        { "type": "block-dirty-bitmap-add",
          "data": { "node": "drive0", "name": "bitmapC",
                    "granularity": granularity }},
        # Purely extraneous, but test that it works:
        { "type": "block-dirty-bitmap-disable",
          "data": { "node": "drive0", "name": "bitmapC" }},
        { "type": "block-dirty-bitmap-enable",
          "data": { "node": "drive0", "name": "bitmapC" }},
    ])

    log('\n--- Emulating further writes ---\n')
    # Dirties 6 clusters, 3 of which are new in contrast to "A".
    # A = 64 * 1024 * (4 + 3) = 458752
    # C = 64 * 1024 * 6       = 393216
    for p in overwrite:
        cmd = "write -P%s %s %s" % p
        log(cmd)
        log(vm.hmp_qemu_io("drive0", cmd))

    log('\n--- Disabling A & C ---\n')
    vm.qmp_log("transaction", indent=2, actions=[
        { "type": "block-dirty-bitmap-disable",
          "data": { "node": "drive0", "name": "bitmapA" }},
        { "type": "block-dirty-bitmap-disable",
          "data": { "node": "drive0", "name": "bitmapC" }}
    ])

    # A: 7 clusters
    # B: 4 clusters
    # C: 6 clusters
    log(query_bitmaps(vm), indent=2)

    log('\n--- Submitting & Aborting Merge Transaction ---\n')
    vm.qmp_log("transaction", indent=2, actions=[
        { "type": "block-dirty-bitmap-add",
          "data": { "node": "drive0", "name": "bitmapD",
                    "disabled": True, "granularity": granularity }},
        { "type": "block-dirty-bitmap-merge",
          "data": { "node": "drive0", "target": "bitmapD",
                    "bitmaps": ["bitmapB", "bitmapC"] }},
        { "type": "abort", "data": {}}
    ])
    log(query_bitmaps(vm), indent=2)

    log('\n--- Creating D as a merge of B & C ---\n')
    # Good hygiene: create a disabled bitmap as a merge target.
    vm.qmp_log("transaction", indent=2, actions=[
        { "type": "block-dirty-bitmap-add",
          "data": { "node": "drive0", "name": "bitmapD",
                    "disabled": True, "granularity": granularity }},
        { "type": "block-dirty-bitmap-merge",
          "data": { "node": "drive0", "target": "bitmapD",
                    "bitmaps": ["bitmapB", "bitmapC"] }}
    ])

    # A and D should now both have 7 clusters apiece.
    # B and C remain unchanged with 4 and 6 respectively.
    log(query_bitmaps(vm), indent=2)

    # A and D should be equivalent.
    # Some formats round the size of the disk, so don't print the checksums.
    check_a = vm.qmp('x-debug-block-dirty-bitmap-sha256',
                     node="drive0", name="bitmapA")['return']['sha256']
    check_d = vm.qmp('x-debug-block-dirty-bitmap-sha256',
                     node="drive0", name="bitmapD")['return']['sha256']
    assert(check_a == check_d)

    log('\n--- Removing bitmaps A, B, C, and D ---\n')
    vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="bitmapA")
    vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="bitmapB")
    vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="bitmapC")
    vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="bitmapD")

    log('\n--- Final Query ---\n')
    log(query_bitmaps(vm), indent=2)

    log('\n--- Done ---\n')
    vm.shutdown()
