/*
 * ******************************************************
 * Copyright 2016-2019 VMware, Inc.  All Rights Reserved.
 * ******************************************************
 */

using AppUtil;
using System;
using System.Collections.Generic;
using VsanHealthApi;

namespace VsanHealthSdk
{
    class VsanIscsiSample
    {
        private static AppUtil.AppUtil vimConn = null;
        private static VsanhealthService vsanHealthConn = null;

        private static ManagedObjectReference vsanVitSystem = null;
        private static ManagedObjectReference vsanClusterConfigSystem = null;

        public VsanIscsiSample(string[] args)
        {
            vimConn = AppUtil.AppUtil.initialize("ClusterStatus",
                VsanHealthSdk.VsanIscsiSample.ConstructOptions(), args);
            Dictionary<string, ManagedObjectReference> vsanSystems = VsanApiHelper.GetVsanMos();
            vsanVitSystem = vsanSystems[VsanApiHelper.VSAN_VC_ISCSI_TARGET_SYSTEM_VALUE];
            vsanClusterConfigSystem = vsanSystems[VsanApiHelper.VSAN_VC_CLUSTER_CONFIG_SYSTEM_VALUE];
        }

        public String GetClusterName()
        {
            return vimConn.get_option("clusterName");
        }

        public ManagedObjectReference Connect()
        {
            vimConn.connect();
            vsanHealthConn = VsanApiHelper.ConstructVsanHealthConnection(vimConn);

            if (VsanApiHelper.IsEsx(vimConn))
            {
                return null;
            }

            ManagedObjectReference clusterMoRef = VsanApiHelper.convertMo(
                vimConn._svcUtil.getEntityByName("ClusterComputeResource", GetClusterName()));
            return clusterMoRef;
        }

        public void Disconnect()
        {
            vimConn.disConnect();
        }

        public void EnableIscsiService(ManagedObjectReference cluster)
        {
            VsanIscsiTargetServiceDefaultConfigSpec vsanConfigSpec = new VsanIscsiTargetServiceDefaultConfigSpec();
            vsanConfigSpec.networkInterface = "vmk0";
            vsanConfigSpec.port = 2300;

            VsanIscsiTargetServiceSpec enableSpec = new VsanIscsiTargetServiceSpec();
            enableSpec.defaultConfig = vsanConfigSpec;
            enableSpec.enabledSpecified = true;
            enableSpec.enabled = true;
            VimVsanReconfigSpec reconfigSpec = new VimVsanReconfigSpec();
            reconfigSpec.iscsiSpec = enableSpec;
            reconfigSpec.modify = true;

            ManagedObjectReference vsanTask = vsanHealthConn.VsanClusterReconfig(
                vsanClusterConfigSystem, cluster, reconfigSpec);
            VsanApiHelper.monitorTask(vimConn, "Enable iSCSI service", vsanTask);
        }

        public void CreateIscsiTargetAndLun(ManagedObjectReference cluster, String targetAlias)
        {
            VsanIscsiTargetSpec targetSpec = new VsanIscsiTargetSpec();
            targetSpec.alias = targetAlias;
            targetSpec.iqn = "iqn.2015-08.com.vmware:vit.target";
            ManagedObjectReference vsanTask = vsanHealthConn.VsanVitAddIscsiTarget(
                  vsanVitSystem, cluster, targetSpec);
            VsanApiHelper.monitorTask(vimConn, "Create vSAN iSCSI target", vsanTask);

            int lunSize = 1 * 1024 * 1024 * 1024;
            VsanIscsiLUNSpec lunSpec = new VsanIscsiLUNSpec();
            lunSpec.lunSize = lunSize;
            vsanTask = vsanHealthConn.VsanVitAddIscsiLUN(
                  vsanVitSystem, cluster, targetAlias, lunSpec);
            VsanApiHelper.monitorTask(vimConn, "Create vSAN iSCSI LUN", vsanTask);
        }

        public void DeleteIscsiTargetAndLun(ManagedObjectReference cluster, string targetAlias)
        {
            ManagedObjectReference task =
                vsanHealthConn.VsanVitRemoveIscsiLUN(vsanVitSystem, cluster, targetAlias, 0);
            VsanApiHelper.monitorTask(vimConn, "Remove vSAN iSCSI LUN", task);
            task = vsanHealthConn.VsanVitRemoveIscsiTarget(vsanVitSystem, cluster, targetAlias);
            VsanApiHelper.monitorTask(vimConn, "Remove vSAN iSCSI Target", task);
        }

        public void DisableIscsiService(ManagedObjectReference cluster)
        {
            VsanIscsiTargetServiceSpec disableSpec = new VsanIscsiTargetServiceSpec();
            disableSpec.enabled = false;

            VimVsanReconfigSpec reconfigSpec = new VimVsanReconfigSpec();
            reconfigSpec.iscsiSpec = disableSpec;
            reconfigSpec.modify = true;
            ManagedObjectReference vsanTask = vsanHealthConn.VsanClusterReconfig(
                vsanClusterConfigSystem, cluster, reconfigSpec);
            VsanApiHelper.monitorTask(vimConn, "Disable iSCSI service", vsanTask);
        }

        private static OptionSpec[] ConstructOptions()
        {
            OptionSpec[] useroptions = new OptionSpec[1];
            useroptions[0] = new OptionSpec("clusterName", "String", 1,
                                            "Specifies the name of the cluster",
                                            null);
            return useroptions;
        }

    }
}
