package testing

import (
	"fmt"
	"net/http"
	"testing"
	"time"

	"github.com/gophercloud/gophercloud/v2"
	"github.com/gophercloud/gophercloud/v2/openstack/container/v1/capsules"
	th "github.com/gophercloud/gophercloud/v2/testhelper"
	"github.com/gophercloud/gophercloud/v2/testhelper/client"
)

// ValidJSONTemplate is a valid OpenStack Capsule template in JSON format
const ValidJSONTemplate = `
{
  "capsuleVersion": "beta",
  "kind": "capsule",
  "metadata": {
    "labels": {
      "app": "web",
      "app1": "web1"
    },
    "name": "template"
  },
  "spec": {
    "restartPolicy": "Always",
    "containers": [
      {
        "command": [
          "/bin/bash"
        ],
        "env": {
          "ENV1": "/usr/local/bin",
          "ENV2": "/usr/bin"
        },
        "image": "ubuntu",
        "imagePullPolicy": "ifnotpresent",
        "ports": [
          {
            "containerPort": 80,
            "hostPort": 80,
            "name": "nginx-port",
            "protocol": "TCP"
          }
        ],
        "resources": {
          "requests": {
            "cpu": 1,
            "memory": 1024
          }
        },
        "workDir": "/root"
      }
    ]
  }
}
`

// ValidYAMLTemplate is a valid OpenStack Capsule template in YAML format
const ValidYAMLTemplate = `
capsuleVersion: beta
kind: capsule
metadata:
  name: template
  labels:
    app: web
    app1: web1
spec:
  restartPolicy: Always
  containers:
  - image: ubuntu
    command:
      - "/bin/bash"
    imagePullPolicy: ifnotpresent
    workDir: /root
    ports:
      - name: nginx-port
        containerPort: 80
        hostPort: 80
        protocol: TCP
    resources:
      requests:
        cpu: 1
        memory: 1024
    env:
      ENV1: /usr/local/bin
      ENV2: /usr/bin
`

// ValidJSONTemplateParsed is the expected parsed version of ValidJSONTemplate
var ValidJSONTemplateParsed = map[string]any{
	"capsuleVersion": "beta",
	"kind":           "capsule",
	"metadata": map[string]any{
		"name": "template",
		"labels": map[string]string{
			"app":  "web",
			"app1": "web1",
		},
	},
	"spec": map[string]any{
		"restartPolicy": "Always",
		"containers": []map[string]any{
			{
				"image": "ubuntu",
				"command": []any{
					"/bin/bash",
				},
				"imagePullPolicy": "ifnotpresent",
				"workDir":         "/root",
				"ports": []any{
					map[string]any{
						"name":          "nginx-port",
						"containerPort": float64(80),
						"hostPort":      float64(80),
						"protocol":      "TCP",
					},
				},
				"resources": map[string]any{
					"requests": map[string]any{
						"cpu":    float64(1),
						"memory": float64(1024),
					},
				},
				"env": map[string]any{
					"ENV1": "/usr/local/bin",
					"ENV2": "/usr/bin",
				},
			},
		},
	},
}

// ValidYAMLTemplateParsed is the expected parsed version of ValidYAMLTemplate
var ValidYAMLTemplateParsed = map[string]any{
	"capsuleVersion": "beta",
	"kind":           "capsule",
	"metadata": map[string]any{
		"name": "template",
		"labels": map[string]string{
			"app":  "web",
			"app1": "web1",
		},
	},
	"spec": map[any]any{
		"restartPolicy": "Always",
		"containers": []map[any]any{
			{
				"image": "ubuntu",
				"command": []any{
					"/bin/bash",
				},
				"imagePullPolicy": "ifnotpresent",
				"workDir":         "/root",
				"ports": []any{
					map[any]any{
						"name":          "nginx-port",
						"containerPort": 80,
						"hostPort":      80,
						"protocol":      "TCP",
					},
				},
				"resources": map[any]any{
					"requests": map[any]any{
						"cpu":    1,
						"memory": 1024,
					},
				},
				"env": map[any]any{
					"ENV1": "/usr/local/bin",
					"ENV2": "/usr/bin",
				},
			},
		},
	},
}

const CapsuleGetBody_OldTime = `
{
  "uuid": "cc654059-1a77-47a3-bfcf-715bde5aad9e",
  "status": "Running",
  "user_id": "d33b18c384574fd2a3299447aac285f0",
  "project_id": "6b8ffef2a0ac42ee87887b9cc98bdf68",
  "cpu": 1,
  "memory": "1024M",
  "meta_name": "test",
  "meta_labels": {"web": "app"},
  "created_at": "2018-01-12 09:37:25+00:00",
  "updated_at": "2018-01-12 09:37:26+00:00",
  "links": [
    {
      "href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
      "rel": "self"
    },
    {
      "href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
      "rel": "bookmark"
    }
  ],
  "capsule_version": "beta",
  "restart_policy":  "always",
  "containers_uuids": ["1739e28a-d391-4fd9-93a5-3ba3f29a4c9b"],
  "addresses": {
    "b1295212-64e1-471d-aa01-25ff46f9818d": [
      {
        "version": 4,
        "preserve_on_delete": false,
        "addr": "172.24.4.11",
        "port": "8439060f-381a-4386-a518-33d5a4058636",
        "subnet_id": "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a"
      }
    ]
  },
  "volumes_info": {
    "67618d54-dd55-4f7e-91b3-39ffb3ba7f5f": [
      "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b"
    ]
  },
  "host": "test-host",
  "status_reason": "No reason",
  "containers": [
    {
      "addresses": {
        "b1295212-64e1-471d-aa01-25ff46f9818d": [
          {
            "version": 4,
            "preserve_on_delete": false,
            "addr": "172.24.4.11",
            "port": "8439060f-381a-4386-a518-33d5a4058636",
            "subnet_id": "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a"
          }
        ]
      },
      "image": "test",
      "labels": {"foo": "bar"},
      "created_at": "2018-01-12 09:37:25+00:00",
      "updated_at": "2018-01-12 09:37:26+00:00",
      "started_at": "2018-01-12 09:37:26+00:00",
      "workdir": "/root",
      "disk": 0,
      "security_groups": ["default"],
      "image_pull_policy": "ifnotpresent",
      "task_state": "Creating",
      "user_id": "d33b18c384574fd2a3299447aac285f0",
      "project_id": "6b8ffef2a0ac42ee87887b9cc98bdf68",
      "uuid": "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b",
      "hostname": "test-hostname",
      "environment": {"USER1": "test"},
      "memory": "1024M",
      "status": "Running",
      "auto_remove": false,
      "auto_heal": false,
      "host": "test-host",
      "image_driver": "docker",
      "status_detail": "Just created",
      "status_reason": "No reason",
      "name": "test-demo-omicron-13",
      "restart_policy": {
        "MaximumRetryCount": "0",
        "Name": "always"
      },
      "ports": [80],
      "command": ["testcmd"],
      "runtime": "runc",
      "cpu": 1,
      "interactive": true
    }
  ]
}`

const CapsuleGetBody_NewTime = `
{
  "uuid": "cc654059-1a77-47a3-bfcf-715bde5aad9e",
  "status": "Running",
  "user_id": "d33b18c384574fd2a3299447aac285f0",
  "project_id": "6b8ffef2a0ac42ee87887b9cc98bdf68",
  "cpu": 1,
  "memory": "1024M",
  "meta_name": "test",
  "meta_labels": {"web": "app"},
  "created_at": "2018-01-12 09:37:25",
  "updated_at": "2018-01-12 09:37:26",
  "links": [
    {
      "href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
      "rel": "self"
    },
    {
      "href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
      "rel": "bookmark"
    }
  ],
  "capsule_version": "beta",
  "restart_policy":  "always",
  "containers_uuids": ["1739e28a-d391-4fd9-93a5-3ba3f29a4c9b"],
  "addresses": {
    "b1295212-64e1-471d-aa01-25ff46f9818d": [
      {
        "version": 4,
        "preserve_on_delete": false,
        "addr": "172.24.4.11",
        "port": "8439060f-381a-4386-a518-33d5a4058636",
        "subnet_id": "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a"
      }
    ]
  },
  "volumes_info": {
    "67618d54-dd55-4f7e-91b3-39ffb3ba7f5f": [
      "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b"
    ]
  },
  "host": "test-host",
  "status_reason": "No reason",
  "containers": [
    {
      "addresses": {
        "b1295212-64e1-471d-aa01-25ff46f9818d": [
          {
            "version": 4,
            "preserve_on_delete": false,
            "addr": "172.24.4.11",
            "port": "8439060f-381a-4386-a518-33d5a4058636",
            "subnet_id": "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a"
          }
        ]
      },
      "image": "test",
      "labels": {"foo": "bar"},
      "created_at": "2018-01-12 09:37:25",
      "updated_at": "2018-01-12 09:37:26",
      "started_at": "2018-01-12 09:37:26",
      "workdir": "/root",
      "disk": 0,
      "security_groups": ["default"],
      "image_pull_policy": "ifnotpresent",
      "task_state": "Creating",
      "user_id": "d33b18c384574fd2a3299447aac285f0",
      "project_id": "6b8ffef2a0ac42ee87887b9cc98bdf68",
      "uuid": "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b",
      "hostname": "test-hostname",
      "environment": {"USER1": "test"},
      "memory": "1024M",
      "status": "Running",
      "auto_remove": false,
      "auto_heal": false,
      "host": "test-host",
      "image_driver": "docker",
      "status_detail": "Just created",
      "status_reason": "No reason",
      "name": "test-demo-omicron-13",
      "restart_policy": {
        "MaximumRetryCount": "0",
        "Name": "always"
      },
      "ports": [80],
      "command": ["testcmd"],
      "runtime": "runc",
      "cpu": 1,
      "interactive": true
    }
  ]
}`

const CapsuleListBody = `
{
  "capsules": [
    {
      "uuid": "cc654059-1a77-47a3-bfcf-715bde5aad9e",
      "status": "Running",
      "user_id": "d33b18c384574fd2a3299447aac285f0",
      "project_id": "6b8ffef2a0ac42ee87887b9cc98bdf68",
      "cpu": 1,
      "memory": "1024M",
      "meta_name": "test",
      "meta_labels": {"web": "app"},
      "created_at": "2018-01-12 09:37:25+00:00",
      "updated_at": "2018-01-12 09:37:25+01:00",
      "links": [
        {
          "href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
          "rel": "self"
        },
        {
          "href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
          "rel": "bookmark"
        }
      ],
      "capsule_version": "beta",
      "restart_policy":  "always",
      "containers_uuids": ["1739e28a-d391-4fd9-93a5-3ba3f29a4c9b", "d1469e8d-bcbc-43fc-b163-8b9b6a740930"],
      "addresses": {
        "b1295212-64e1-471d-aa01-25ff46f9818d": [
          {
            "version": 4,
            "preserve_on_delete": false,
            "addr": "172.24.4.11",
            "port": "8439060f-381a-4386-a518-33d5a4058636",
            "subnet_id": "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a"
          }
        ]
      },
      "volumes_info": {
        "67618d54-dd55-4f7e-91b3-39ffb3ba7f5f": [
          "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b"
        ]
      },
      "host": "test-host",
      "status_reason": "No reason"
    }
  ]
}`

const CapsuleV132ListBody = `
{
  "capsules": [
    {
      "uuid": "cc654059-1a77-47a3-bfcf-715bde5aad9e",
      "status": "Running",
      "user_id": "d33b18c384574fd2a3299447aac285f0",
      "project_id": "6b8ffef2a0ac42ee87887b9cc98bdf68",
      "cpu": 1,
      "memory": "1024M",
      "name": "test",
      "labels": {"web": "app"},
      "created_at": "2018-01-12 09:37:25",
      "updated_at": "2018-01-12 09:37:25",
      "links": [
        {
          "href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
          "rel": "self"
        },
        {
          "href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
          "rel": "bookmark"
        }
      ],
      "restart_policy": {
        "MaximumRetryCount": "0",
        "Name": "always"
      },
      "addresses": {
        "b1295212-64e1-471d-aa01-25ff46f9818d": [
          {
            "version": 4,
            "preserve_on_delete": false,
            "addr": "172.24.4.11",
            "port": "8439060f-381a-4386-a518-33d5a4058636",
            "subnet_id": "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a"
          }
        ]
      },
      "host": "test-host",
      "status_reason": "No reason"
    }
  ]
}`

func GetFakeContainer() capsules.Container {
	createdAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:25")
	updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:26")
	startedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:26")

	return capsules.Container{
		Name:      "test-demo-omicron-13",
		UUID:      "1739e28a-d391-4fd9-93a5-3ba3f29a4c9b",
		UserID:    "d33b18c384574fd2a3299447aac285f0",
		ProjectID: "6b8ffef2a0ac42ee87887b9cc98bdf68",
		CreatedAt: createdAt,
		UpdatedAt: updatedAt,
		StartedAt: startedAt,
		CPU:       float64(1),
		Memory:    "1024M",
		Host:      "test-host",
		Status:    "Running",
		Image:     "test",
		Labels: map[string]string{
			"foo": "bar",
		},
		WorkDir: "/root",
		Disk:    0,
		Command: []string{
			"testcmd",
		},
		Ports: []int{
			80,
		},
		SecurityGroups: []string{
			"default",
		},
		ImagePullPolicy: "ifnotpresent",
		Runtime:         "runc",
		TaskState:       "Creating",
		HostName:        "test-hostname",
		Environment: map[string]string{
			"USER1": "test",
		},
		StatusReason: "No reason",
		StatusDetail: "Just created",
		ImageDriver:  "docker",
		Interactive:  true,
		AutoRemove:   false,
		AutoHeal:     false,
		RestartPolicy: map[string]string{
			"MaximumRetryCount": "0",
			"Name":              "always",
		},
		Addresses: map[string][]capsules.Address{
			"b1295212-64e1-471d-aa01-25ff46f9818d": {
				{
					PreserveOnDelete: false,
					Addr:             "172.24.4.11",
					Port:             "8439060f-381a-4386-a518-33d5a4058636",
					Version:          float64(4),
					SubnetID:         "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a",
				},
			},
		},
	}
}

func GetFakeCapsule() capsules.Capsule {
	createdAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:25")
	updatedAt, _ := time.Parse(gophercloud.RFC3339ZNoTNoZ, "2018-01-12 09:37:26")

	return capsules.Capsule{
		UUID:      "cc654059-1a77-47a3-bfcf-715bde5aad9e",
		Status:    "Running",
		UserID:    "d33b18c384574fd2a3299447aac285f0",
		ProjectID: "6b8ffef2a0ac42ee87887b9cc98bdf68",
		CreatedAt: createdAt,
		UpdatedAt: updatedAt,
		CPU:       float64(1),
		Memory:    "1024M",
		MetaName:  "test",
		Links: []any{
			map[string]any{
				"href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
				"rel":  "self",
			},
			map[string]any{
				"href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
				"rel":  "bookmark",
			},
		},
		CapsuleVersion: "beta",
		RestartPolicy:  "always",
		MetaLabels: map[string]string{
			"web": "app",
		},
		ContainersUUIDs: []string{
			"1739e28a-d391-4fd9-93a5-3ba3f29a4c9b",
		},
		Addresses: map[string][]capsules.Address{
			"b1295212-64e1-471d-aa01-25ff46f9818d": {
				{
					PreserveOnDelete: false,
					Addr:             "172.24.4.11",
					Port:             "8439060f-381a-4386-a518-33d5a4058636",
					Version:          float64(4),
					SubnetID:         "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a",
				},
			},
		},
		VolumesInfo: map[string][]string{
			"67618d54-dd55-4f7e-91b3-39ffb3ba7f5f": {
				"1739e28a-d391-4fd9-93a5-3ba3f29a4c9b",
			},
		},
		Host:         "test-host",
		StatusReason: "No reason",
		Containers: []capsules.Container{
			GetFakeContainer(),
		},
	}
}

func GetFakeCapsuleV132() capsules.CapsuleV132 {
	return capsules.CapsuleV132{
		UUID:      "cc654059-1a77-47a3-bfcf-715bde5aad9e",
		Status:    "Running",
		UserID:    "d33b18c384574fd2a3299447aac285f0",
		ProjectID: "6b8ffef2a0ac42ee87887b9cc98bdf68",
		CPU:       float64(1),
		Memory:    "1024M",
		MetaName:  "test",
		Links: []any{
			map[string]any{
				"href": "http://10.10.10.10/v1/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
				"rel":  "self",
			},
			map[string]any{
				"href": "http://10.10.10.10/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e",
				"rel":  "bookmark",
			},
		},
		RestartPolicy: map[string]string{
			"MaximumRetryCount": "0",
			"Name":              "always",
		},
		MetaLabels: map[string]string{
			"web": "app",
		},
		Addresses: map[string][]capsules.Address{
			"b1295212-64e1-471d-aa01-25ff46f9818d": {
				{
					PreserveOnDelete: false,
					Addr:             "172.24.4.11",
					Port:             "8439060f-381a-4386-a518-33d5a4058636",
					Version:          float64(4),
					SubnetID:         "4a2bcd64-93ad-4436-9f48-3a7f9b267e0a",
				},
			},
		},
		Host:         "test-host",
		StatusReason: "No reason",
		Containers: []capsules.Container{
			GetFakeContainer(),
		},
	}
}

// HandleCapsuleGetOldTimeSuccessfully test setup
func HandleCapsuleGetOldTimeSuccessfully(t *testing.T, fakeServer th.FakeServer) {
	fakeServer.Mux.HandleFunc("/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", func(w http.ResponseWriter, r *http.Request) {
		th.TestMethod(t, r, "GET")
		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)

		w.WriteHeader(http.StatusOK)
		w.Header().Add("Content-Type", "application/json")
		fmt.Fprint(w, CapsuleGetBody_OldTime)
	})
}

// HandleCapsuleGetNewTimeSuccessfully test setup
func HandleCapsuleGetNewTimeSuccessfully(t *testing.T, fakeServer th.FakeServer) {
	fakeServer.Mux.HandleFunc("/capsules/cc654059-1a77-47a3-bfcf-715bde5aad9e", func(w http.ResponseWriter, r *http.Request) {
		th.TestMethod(t, r, "GET")
		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)

		w.WriteHeader(http.StatusOK)
		w.Header().Add("Content-Type", "application/json")
		fmt.Fprint(w, CapsuleGetBody_NewTime)
	})
}

// HandleCapsuleCreateSuccessfully creates an HTTP handler at `/capsules` on the test handler mux
// that responds with a `Create` response.
func HandleCapsuleCreateSuccessfully(t *testing.T, fakeServer th.FakeServer) {
	fakeServer.Mux.HandleFunc("/capsules", func(w http.ResponseWriter, r *http.Request) {
		th.TestMethod(t, r, "POST")
		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
		th.TestHeader(t, r, "Accept", "application/json")
		w.WriteHeader(http.StatusAccepted)
		fmt.Fprint(w, CapsuleGetBody_NewTime)
	})
}

// HandleCapsuleListSuccessfully test setup
func HandleCapsuleListSuccessfully(t *testing.T, fakeServer th.FakeServer) {
	fakeServer.Mux.HandleFunc("/capsules/", func(w http.ResponseWriter, r *http.Request) {
		th.TestMethod(t, r, "GET")
		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)

		w.Header().Add("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, CapsuleListBody)
	})
}

// HandleCapsuleV132ListSuccessfully test setup
func HandleCapsuleV132ListSuccessfully(t *testing.T, fakeServer th.FakeServer) {
	fakeServer.Mux.HandleFunc("/capsules/", func(w http.ResponseWriter, r *http.Request) {
		th.TestMethod(t, r, "GET")
		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)

		w.Header().Add("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, CapsuleV132ListBody)
	})
}

func HandleCapsuleDeleteSuccessfully(t *testing.T, fakeServer th.FakeServer) {
	fakeServer.Mux.HandleFunc("/capsules/963a239d-3946-452b-be5a-055eab65a421", func(w http.ResponseWriter, r *http.Request) {
		th.TestMethod(t, r, "DELETE")
		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
		w.WriteHeader(http.StatusNoContent)
	})
}
