// Copyright 2016 CNI authors
//
// 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package testutils

import (
	"io"
	"os"

	"github.com/containernetworking/cni/pkg/skel"
	"github.com/containernetworking/cni/pkg/types"
	"github.com/containernetworking/cni/pkg/version"
)

func envCleanup() {
	os.Unsetenv("CNI_COMMAND")
	os.Unsetenv("CNI_PATH")
	os.Unsetenv("CNI_NETNS")
	os.Unsetenv("CNI_IFNAME")
	os.Unsetenv("CNI_CONTAINERID")
	os.Unsetenv("CNI_NETNS_OVERRIDE")
}

func CmdAdd(cniNetns, cniContainerID, cniIfname string, conf []byte, f func() error) (types.Result, []byte, error) {
	os.Setenv("CNI_COMMAND", "ADD")
	os.Setenv("CNI_PATH", os.Getenv("PATH"))
	os.Setenv("CNI_NETNS", cniNetns)
	os.Setenv("CNI_IFNAME", cniIfname)
	os.Setenv("CNI_CONTAINERID", cniContainerID)
	os.Setenv("CNI_NETNS_OVERRIDE", "1")
	defer envCleanup()

	// Redirect stdout to capture plugin result
	oldStdout := os.Stdout
	r, w, err := os.Pipe()
	if err != nil {
		return nil, nil, err
	}

	os.Stdout = w
	err = f()
	w.Close()

	var out []byte
	if err == nil {
		out, err = io.ReadAll(r)
	}
	os.Stdout = oldStdout

	// Return errors after restoring stdout so Ginkgo will correctly
	// emit verbose error information on stdout
	if err != nil {
		return nil, nil, err
	}

	// Plugin must return result in same version as specified in netconf
	versionDecoder := &version.ConfigDecoder{}
	confVersion, err := versionDecoder.Decode(conf)
	if err != nil {
		return nil, nil, err
	}

	result, err := version.NewResult(confVersion, out)
	if err != nil {
		return nil, nil, err
	}

	return result, out, nil
}

func CmdAddWithArgs(args *skel.CmdArgs, f func() error) (types.Result, []byte, error) {
	return CmdAdd(args.Netns, args.ContainerID, args.IfName, args.StdinData, f)
}

func CmdCheck(cniNetns, cniContainerID, cniIfname string, f func() error) error {
	os.Setenv("CNI_COMMAND", "CHECK")
	os.Setenv("CNI_PATH", os.Getenv("PATH"))
	os.Setenv("CNI_NETNS", cniNetns)
	os.Setenv("CNI_IFNAME", cniIfname)
	os.Setenv("CNI_CONTAINERID", cniContainerID)
	os.Setenv("CNI_NETNS_OVERRIDE", "1")
	defer envCleanup()

	return f()
}

func CmdCheckWithArgs(args *skel.CmdArgs, f func() error) error {
	return CmdCheck(args.Netns, args.ContainerID, args.IfName, f)
}

func CmdDel(cniNetns, cniContainerID, cniIfname string, f func() error) error {
	os.Setenv("CNI_COMMAND", "DEL")
	os.Setenv("CNI_PATH", os.Getenv("PATH"))
	os.Setenv("CNI_NETNS", cniNetns)
	os.Setenv("CNI_IFNAME", cniIfname)
	os.Setenv("CNI_CONTAINERID", cniContainerID)
	os.Setenv("CNI_NETNS_OVERRIDE", "1")
	defer envCleanup()

	return f()
}

func CmdDelWithArgs(args *skel.CmdArgs, f func() error) error {
	return CmdDel(args.Netns, args.ContainerID, args.IfName, f)
}

func CmdStatus(f func() error) error {
	os.Setenv("CNI_COMMAND", "STATUS")
	os.Setenv("CNI_PATH", os.Getenv("PATH"))
	os.Setenv("CNI_NETNS_OVERRIDE", "1")
	defer envCleanup()

	return f()
}
