/* Copyright Contributors to the Open Cluster Management project */

import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Cluster, ClusterStatus } from '../../../../../lib/get-cluster'
import { mockBadRequestStatus, nockGet } from '../../../../../lib/nock-util'
import { createDownloadFile } from '../../../../../lib/utils'
import { ClusterContext } from '../ClusterDetails/ClusterDetails'
import { DownloadConfigurationDropdown } from './DownloadConfigurationDropdown'

jest.mock('../../../../../lib/utils', () => ({
    createDownloadFile: jest.fn(),
}))

const mockCluster: Cluster = {
    name: 'test-cluster',
    displayName: 'test-cluster',
    namespace: 'test-cluster',
    status: ClusterStatus.ready,
    distribution: {
        k8sVersion: '1.19',
        ocp: {
            version: '4.6',
            availableUpdates: [],
            desiredVersion: '4.6',
            upgradeFailed: false,
        },
        displayVersion: '4.6',
    },
    labels: undefined,
    nodes: undefined,
    kubeApiServer: '',
    consoleURL: '',
    hive: {
        isHibernatable: true,
        clusterPool: undefined,
        secrets: {
            installConfig: 'test-cluster-install-config',
            kubeadmin: 'test-cluster-0-fk6c9-admin-password',
            kubeconfig: 'test-cluster-0-fk6c9-admin-kubeconfig',
        },
    },
    isHive: true,
    isManaged: true,
}

const mockInstallConfig = {
    kind: 'Secret',
    apiVersion: 'v1',
    metadata: {
        name: 'test-cluster-install-config',
        namespace: 'test-cluster',
        selfLink: '/api/v1/namespaces/test-cluster/secrets/test-cluster-install-config',
        uid: '9b73a4b6-6001-4e78-aea6-70937cf3284b',
        resourceVersion: '54086664',
    },
    data: {
        'install-config.yaml':
            'YXBpVmVyc2lvbjogdjEKbWV0YWRhdGE6CiAgbmFtZTogc3dlaW1lci10ZXN0CmJhc2VEb21haW46IGRldjAyLnJlZC1jaGVzdGVyZmllbGQuY29tCmNvbnRyb2xQbGFuZToKICBoeXBlcnRocmVhZGluZzogRW5hYmxlZAogIG5hbWU6IG1hc3RlcgogIHJlcGxpY2FzOiAzCiAgcGxhdGZvcm06CiAgICBhd3M6CiAgICAgIHJvb3RWb2x1bWU6CiAgICAgICAgaW9wczogNDAwMAogICAgICAgIHNpemU6IDEwMAogICAgICAgIHR5cGU6IGlvMQogICAgICB0eXBlOiBtNS54bGFyZ2UKY29tcHV0ZToKLSBoeXBlcnRocmVhZGluZzogRW5hYmxlZAogIG5hbWU6IHdvcmtlcgogIHJlcGxpY2FzOiAzCiAgcGxhdGZvcm06CiAgICBhd3M6CiAgICAgIHJvb3RWb2x1bWU6CiAgICAgICAgaW9wczogMjAwMAogICAgICAgIHNpemU6IDEwMAogICAgICAgIHR5cGU6IGlvMQogICAgICB0eXBlOiBtNS54bGFyZ2UKbmV0d29ya2luZzoKICBjbHVzdGVyTmV0d29yazoKICAtIGNpZHI6IDEwLjEyOC4wLjAvMTQKICAgIGhvc3RQcmVmaXg6IDIzCiAgbWFjaGluZUNJRFI6IDEwLjAuMC4wLzE2CiAgbmV0d29ya1R5cGU6IE9WTkt1YmVybmV0ZXMKICBzZXJ2aWNlTmV0d29yazoKICAtIDE3Mi4zMC4wLjAvMTYKcGxhdGZvcm06CiAgYXdzOgogICAgcmVnaW9uOiB1cy1lYXN0LTEKcHVsbFNlY3JldDogIiIgIyBza2lwLCBoaXZlIHdpbGwgaW5qZWN0IGJhc2VkIG9uIGl0J3Mgc2VjcmV0cwpzc2hLZXk6IHwtCiAgICBzc2gtcnNhIEFBQUFCM056YUMxeWMyRUFBQUFEQVFBQkFBQUNBUURXZklWbzFCUXJQcGRxRHBPTHNSbjRNVmJtZ1NrQjJQaFA3U1pIdTZaVGtGaFh0Wk5TV2plalVQNDJLU29jREhlNmJUbXVtUnFObE1hcmFzMi84M2hNbXBwSUd5aHIxbGp1TTltNjJHWDVZRHhrT1Bhb2pNME5UU0Ftc3FVUTJXZWVuT2Vkd0JibjZmd3ppWnIyMmViSUN6cXp6bGhxajhVcXdGeU1KSVVobUtVbnBweUMxYWU2eGdZNTlkY2E2UmdLdEZPZFdwUm5pZkJqdjlHTE1qWXVsQXU2d0o2QVpxeXEwNXY3R0ljMVRxZDNEeDhBL2NsUkt2WmUveGJHQmQxNy9Mc3U5WDFrUy85eCtRaExmNlliTlZIZlc2aUhqaXBoUjVaZzlGVFN3eVZMR094cnRmc3cyWHh0bmlJenA3WVdMMW9ySjk5VVZHM3RicjRpUWhRYmZpV2kyYkUya281U3hRSVU1UDVsUVlpY0JVY202d0dZdnplM3lTalJQQUgzRkVYRTVnS0g1NTd4TUVoYzQ1SzNEWEVkTmU1SVpjL2l1SkN2cy81RkwycEJyUEVvVXI3ZmtQd0NZYkJCSk1EeE1QL3RhZkVwZjM5cmJvZXRKMHNqTHhSQU1BakRvZ0V2Qm1MbUk3WE41V0RCbWJQWStIU1hET0pZbFdrSE1EMWkrY3hHeGtTaUZzcGNwZjlYcHNKanlJNURhNExlY1lxSGViYVZLZVdVeFU4cnhvaVNQMnV6dzB5cWhJbzFzVVc5M0VKM21INitwWHVFR3o2Y1FKWUorb05QM1BhUkZJeTBELzZ2RXhBMERNS282NmsyMHZrQzhHelZ5RVhaM3pUSFF6OVFCa1RVd0RyYXI3Y0c5NWY2ZU92OXFYeTJxTGlESlVQbTRiWjJkUT09IFVTMkoyNzg3QGlibS5jb20K',
    },
    type: 'Opaque',
}

const mockKubeconfig = {
    kind: 'Secret',
    apiVersion: 'v1',
    metadata: {
        name: 'test-cluster-0-fk6c9-admin-kubeconfig',
        namespace: 'test-cluster',
        selfLink: '/api/v1/namespaces/test-cluster/secrets/test-cluster-0-fk6c9-admin-kubeconfig',
        uid: '1494964a-8d7c-4a5a-b295-e501698e6eb4',
        resourceVersion: '54130006',
        labels: {
            'hive.openshift.io/cluster-deployment-name': 'test-cluster',
            'hive.openshift.io/cluster-provision-name': 'test-cluster-0-fk6c9',
            'hive.openshift.io/secret-type': 'kubeconfig',
        },
    },
    data: {
        kubeconfig:
            '[encoded data, 11980 characters]',
    },
    type: 'Opaque',
}

describe('DownloadConfigurationDropdown', () => {
    test('renders', () => {
        render(
            <ClusterContext.Provider value={{ cluster: mockCluster, addons: undefined }}>
                <DownloadConfigurationDropdown canGetSecret={true} />
            </ClusterContext.Provider>
        )
        expect(screen.getByTestId('download-configuration')).toBeInTheDocument()
    })
    test('can download the cluster install-config', async () => {
        nockGet(mockInstallConfig)
        render(
            <ClusterContext.Provider value={{ cluster: mockCluster, addons: undefined }}>
                <DownloadConfigurationDropdown canGetSecret={true} />
            </ClusterContext.Provider>
        )
        userEvent.click(screen.getByTestId('download-configuration'))
        await waitFor(() => screen.getByTestId('install-config.yaml'))
        userEvent.click(screen.getByTestId('install-config.yaml'))
        await waitFor(() => expect(createDownloadFile).toHaveBeenCalled())
    })
    test('can download the cluster kubeconfig', async () => {
        nockGet(mockKubeconfig)
        render(
            <ClusterContext.Provider value={{ cluster: mockCluster, addons: undefined }}>
                <DownloadConfigurationDropdown canGetSecret={true} />
            </ClusterContext.Provider>
        )
        userEvent.click(screen.getByTestId('download-configuration'))
        await waitFor(() => screen.getByTestId('kubeconfig'))
        userEvent.click(screen.getByTestId('kubeconfig'))
        await waitFor(() => expect(createDownloadFile).toHaveBeenCalled())
    })
    test('renders null when secrets are not available', () => {
        render(
            <ClusterContext.Provider value={{ cluster: undefined, addons: undefined }}>
                <DownloadConfigurationDropdown canGetSecret={true} />
            </ClusterContext.Provider>
        )
        expect(screen.queryByTestId('download-configuration')).toBeNull()
    })
    test('handles error case', async () => {
        console.error = jest.fn()
        nockGet(mockKubeconfig, mockBadRequestStatus)
        render(
            <ClusterContext.Provider value={{ cluster: mockCluster, addons: undefined }}>
                <DownloadConfigurationDropdown canGetSecret={true} />
            </ClusterContext.Provider>
        )
        userEvent.click(screen.getByTestId('download-configuration'))
        await waitFor(() => screen.getByTestId('kubeconfig'))
        userEvent.click(screen.getByTestId('kubeconfig'))
        await waitFor(() => expect(console.error).toHaveBeenCalled())
    })
})
