// Copyright 2017 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.package spec

package e2e

import (
	"fmt"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/pingcap/tidb-operator/pkg/util/label"
	"github.com/pingcap/tidb-operator/pkg/volumeprovisioner"
	"github.com/pingcap/tidb-operator/test/e2e/framework"
	apierrs "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/wait"
)

func testDeleteNamespace(f *framework.Framework) {
	clusterName := "e2e-delete"
	var pdCount int32 = 1
	var tidbCount int32 = 1
	var tikvCount int32 = 3

	done := deployCluster(f, e2eNamespaceDelete, clusterName, pdCount, tidbCount, tikvCount)

	By(fmt.Sprintf("When deleting the %s namespace from kubernetes", e2eNamespaceDelete))
	Expect(f.KubeCli.CoreV1().Namespaces().Delete(e2eNamespaceDelete, &metav1.DeleteOptions{})).To(Succeed())

	pvShouldNotBeDeleted(f, clusterName, pdCount+tikvCount)

	By("When manual delete a PV")
	pvList, err := f.KubeCli.CoreV1().PersistentVolumes().List(label.ClusterListOptions(clusterName))
	Expect(err).NotTo(HaveOccurred())

	pv := pvList.Items[0]
	pvName := pv.GetName()
	pv.Annotations[volumeprovisioner.AnnPVManualDeleted] = time.Now().Format(time.RFC3339)
	_, err = f.KubeCli.CoreV1().PersistentVolumes().Update(&pv)
	Expect(err).NotTo(HaveOccurred())

	By("Then this PV should been deleted")
	err = wait.Poll(5*time.Second, 5*time.Minute, func() (bool, error) {
		_, err := f.KubeCli.CoreV1().PersistentVolumes().Get(pvName, metav1.GetOptions{})
		if err != nil && apierrs.IsNotFound(err) {
			return true, nil
		}

		return false, nil
	})
	Expect(err).NotTo(HaveOccurred())

	close(done)
}
