package cn.reghao.tnb.sb.kvm;

import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.libvirt.*;

import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 存储
 *
 * @author reghao
 * @date 2020-10-28 21:44:01
 */
@Slf4j
public class Storage {
    private final String uri;

    public Storage() {
        this.uri = "qemu:///system";
    }

    public void createStoragePool() throws Exception {
        Connect conn = new Connect(uri, false);
        String xml = "/home/reghao/docs/zzz/backend/kvm/xml/pool.xml";
        Document doc = new SAXReader().read(new FileInputStream(xml));
        StoragePool storagePool = conn.storagePoolCreateXML(doc.asXML(), 0);
    }

    public List<StoragePool> listStoragePool() throws Exception {
        Connect conn = new Connect(uri, true);

        List<StoragePool> poolList = new ArrayList<>();
        String[] activePoolNames = conn.listStoragePools();
        String[] inactivePoolNames = conn.listDefinedStoragePools();
        for (String poolName : activePoolNames) {
            StoragePool storagePool = conn.storagePoolLookupByName(poolName);
            poolList.add(storagePool);

            storagePool.isPersistent();
            storagePool.isActive();
            storagePool.getAutostart();
            storagePool.getXMLDesc(0);
            storagePool.getUUIDString();
        }

        return poolList;
    }

    public void deleteStoragePool(String poolName) throws Exception {
        Connect conn = new Connect(uri, false);
        StoragePool storagePool = conn.storagePoolLookupByName(poolName);
        int res = storagePool.isActive();
        if (res == 1) {
            //storagePool.destroy();
            //storagePool.undefine();
            // 释放所有与存储池关联的内存，存储池的状态不会改变
            storagePool.free();
        } else if (res == 0) {
            //
            storagePool.undefine();
            storagePool.free();
        } else {
            throw new Exception("存储池状态错误...");
        }
    }

    public StorageVol createStorageVolume(StoragePool storagePool) throws Exception {
        String xml = "/home/reghao/docs/zzz/backend/kvm/xml/volume.xml";
        Document doc = new SAXReader().read(new FileInputStream(xml));
        return storagePool.storageVolCreateXML(doc.asXML(), 0);
    }

    public List<StorageVol> listStorageVolume(String poolName) throws Exception {
        Connect conn = new Connect(uri, true);
        StoragePool storagePool = conn.storagePoolLookupByName(poolName);

        List<StorageVol> volList = new ArrayList<>();
        String[] volumeNames = storagePool.listVolumes();
        for (String volName : volumeNames) {
            StorageVol storageVol = storagePool.storageVolLookupByName(volName);
            volList.add(storageVol);
            //list.add(storagePool.storageVolLookupByName(vol));
            /*StorageVolInfo volInfo = storageVol.getInfo();
            log.info("存储卷的类型：{}", volInfo.type);
            log.info("存储卷的容量：{}GB", volInfo.capacity / 1024.00 / 1024.00 / 1024.00);
            log.info("存储卷的已用容量：{}GB", volInfo.allocation / 1024.00 / 1024.00 / 1024.00);*/
        }

        return volList;
    }

    public static void cloneVolume(StoragePool storagePool) throws LibvirtException {
        String xmlDesc = "";
        StorageVol cloneVolume = null;
        // StoragePool.BuildFlags.VIR_STORAGE_POOL_BUILD_NEW
        storagePool.storageVolCreateXMLFrom(xmlDesc, cloneVolume, 0);
    }

    public static void main(String[] args) throws Exception {
        Storage storage = new Storage();

        List<StoragePool> storagePools = storage.listStoragePool();
        /*if (storagePools.isEmpty()) {
            StoragePool storagePool = storage.createStoragePool();
            //StorageVol storageVol = storage.createStorageVolume(storagePool);
            return;
        }*/

        for (StoragePool storagePool: storagePools) {
            String poolName = storagePool.getName();
            log.info("存储池: {}", poolName);

            List<StorageVol> storageVols = storage.listStorageVolume(poolName);
            for (StorageVol storageVol : storageVols) {
                // 释放所有指向 volume 的指针(domain)
                //storageVol.free();
                // 物理删除
                //storageVol.delete(0);
                log.info("存储卷：{}", storageVol.getName());
            }
            log.info("---------------------------------------------------------------------");
        }
    }
}
