/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import fetchMock from 'fetch-mock';
import {
  act,
  defaultStore as store,
  render,
  screen,
  userEvent,
  waitFor,
} from 'spec/helpers/testing-library';
import { api } from 'src/hooks/apiResources/queryApi';
import { EmptyState } from '@superset-ui/core/components';
import { DatabaseSelector } from '.';
import type { DatabaseSelectorProps } from './types';

const createProps = (): DatabaseSelectorProps => ({
  db: {
    id: 1,
    database_name: 'test',
    backend: 'test-postgresql',
  },
  formMode: false,
  isDatabaseSelectEnabled: true,
  readOnly: false,
  catalog: null,
  schema: 'public',
  sqlLabMode: true,
  getDbList: jest.fn(),
  handleError: jest.fn(),
  onDbChange: jest.fn(),
  onSchemaChange: jest.fn(),
});

const fakeDatabaseApiResult = {
  count: 2,
  description_columns: {},
  ids: [1, 2],
  label_columns: {
    allow_file_upload: 'Allow Csv Upload',
    allow_ctas: 'Allow Ctas',
    allow_cvas: 'Allow Cvas',
    allow_dml: 'Allow DDL and DML',
    allow_run_async: 'Allow Run Async',
    allows_cost_estimate: 'Allows Cost Estimate',
    allows_subquery: 'Allows Subquery',
    allows_virtual_table_explore: 'Allows Virtual Table Explore',
    disable_data_preview: 'Disables SQL Lab Data Preview',
    disable_drill_to_detail: 'Disable Drill To Detail',
    backend: 'Backend',
    changed_on: 'Changed On',
    changed_on_delta_humanized: 'Changed On Delta Humanized',
    'created_by.first_name': 'Created By First Name',
    'created_by.last_name': 'Created By Last Name',
    database_name: 'Database Name',
    explore_database_id: 'Explore Database Id',
    expose_in_sqllab: 'Expose In Sqllab',
    force_ctas_schema: 'Force Ctas Schema',
    id: 'Id',
  },
  list_columns: [
    'allow_file_upload',
    'allow_ctas',
    'allow_cvas',
    'allow_dml',
    'allow_run_async',
    'allows_cost_estimate',
    'allows_subquery',
    'allows_virtual_table_explore',
    'disable_data_preview',
    'disable_drill_to_detail',
    'backend',
    'changed_on',
    'changed_on_delta_humanized',
    'created_by.first_name',
    'created_by.last_name',
    'database_name',
    'explore_database_id',
    'expose_in_sqllab',
    'force_ctas_schema',
    'id',
  ],
  list_title: 'List Database',
  order_columns: [
    'allow_file_upload',
    'allow_dml',
    'allow_run_async',
    'changed_on',
    'changed_on_delta_humanized',
    'created_by.first_name',
    'database_name',
    'expose_in_sqllab',
  ],
  result: [
    {
      allow_file_upload: false,
      allow_ctas: false,
      allow_cvas: false,
      allow_dml: false,
      allow_run_async: false,
      allows_cost_estimate: null,
      allows_subquery: true,
      allows_virtual_table_explore: true,
      disable_data_preview: false,
      disable_drill_to_detail: false,
      backend: 'postgresql',
      changed_on: '2021-03-09T19:02:07.141095',
      changed_on_delta_humanized: 'a day ago',
      created_by: null,
      database_name: 'test-postgres',
      explore_database_id: 1,
      expose_in_sqllab: true,
      force_ctas_schema: null,
      id: 1,
    },
    {
      allow_csv_upload: false,
      allow_ctas: false,
      allow_cvas: false,
      allow_dml: false,
      allow_run_async: false,
      allows_cost_estimate: null,
      allows_subquery: true,
      allows_virtual_table_explore: true,
      disable_data_preview: false,
      disable_drill_to_detail: false,
      backend: 'mysql',
      changed_on: '2021-03-09T19:02:07.141095',
      changed_on_delta_humanized: 'a day ago',
      created_by: null,
      database_name: 'test-mysql',
      explore_database_id: 1,
      expose_in_sqllab: true,
      force_ctas_schema: null,
      id: 2,
    },
  ],
};

const fakeDatabaseApiResultInReverseOrder = {
  ...fakeDatabaseApiResult,
  ids: [2, 1],
  result: [...fakeDatabaseApiResult.result].reverse(),
};

const fakeSchemaApiResult = {
  count: 2,
  result: ['information_schema', 'public'],
};

const fakeCatalogApiResult = {
  count: 0,
  result: [],
};

const fakeFunctionNamesApiResult = {
  function_names: [],
};

const databaseApiRoute =
  'glob:*/api/v1/database/?*order_column:database_name,order_direction*';
const catalogApiRoute = 'glob:*/api/v1/database/*/catalogs/?*';
const schemaApiRoute = 'glob:*/api/v1/database/*/schemas/?*';
const tablesApiRoute = 'glob:*/api/v1/database/*/tables/*';

function setupFetchMock() {
  fetchMock.get(databaseApiRoute, fakeDatabaseApiResult);
  fetchMock.get(catalogApiRoute, fakeCatalogApiResult);
  fetchMock.get(schemaApiRoute, fakeSchemaApiResult);
  fetchMock.get(tablesApiRoute, fakeFunctionNamesApiResult);
}

beforeEach(() => {
  setupFetchMock();
});

afterEach(() => {
  fetchMock.reset();
  act(() => {
    store.dispatch(api.util.resetApiState());
  });
});

test('Should render', async () => {
  const props = createProps();
  render(<DatabaseSelector {...props} />, { useRedux: true, store });
  expect(await screen.findByTestId('DatabaseSelector')).toBeInTheDocument();
});

test('Refresh should work', async () => {
  const props = createProps();

  render(<DatabaseSelector {...props} />, { useRedux: true, store });

  expect(fetchMock.calls(schemaApiRoute).length).toBe(0);

  const select = screen.getByRole('combobox', {
    name: 'Select schema or type to search schemas: public',
  });

  await userEvent.click(select);

  await waitFor(() => {
    expect(fetchMock.calls(databaseApiRoute).length).toBe(1);
    expect(fetchMock.calls(schemaApiRoute).length).toBe(1);
    expect(props.handleError).toHaveBeenCalledTimes(0);
    expect(props.onDbChange).toHaveBeenCalledTimes(0);
    expect(props.onSchemaChange).toHaveBeenCalledTimes(0);
  });

  // click schema reload
  await userEvent.click(screen.getByRole('button', { name: 'sync' }));

  await waitFor(() => {
    expect(fetchMock.calls(databaseApiRoute).length).toBe(1);
    expect(fetchMock.calls(schemaApiRoute).length).toBe(2);
    expect(props.handleError).toHaveBeenCalledTimes(0);
    expect(props.onDbChange).toHaveBeenCalledTimes(0);
    expect(props.onSchemaChange).toHaveBeenCalledTimes(0);
  });
});

test('Should database select display options', async () => {
  const props = createProps();
  render(<DatabaseSelector {...props} />, { useRedux: true, store });
  const select = screen.getByRole('combobox', {
    name: 'Select database or type to search databases',
  });
  expect(select).toBeInTheDocument();
  await userEvent.click(select);
  expect(await screen.findByText('test-mysql')).toBeInTheDocument();
});

test('should display options in order of the api response', async () => {
  fetchMock.get(databaseApiRoute, fakeDatabaseApiResultInReverseOrder, {
    overwriteRoutes: true,
  });
  const props = createProps();
  render(<DatabaseSelector {...props} db={undefined} />, {
    useRedux: true,
    store,
  });
  const select = screen.getByRole('combobox', {
    name: 'Select database or type to search databases',
  });
  expect(select).toBeInTheDocument();
  await userEvent.click(select);
  const options = await screen.findAllByRole('option');

  expect(options[0]).toHaveTextContent(
    `${fakeDatabaseApiResultInReverseOrder.result[0].id}`,
  );
  expect(options[1]).toHaveTextContent(
    `${fakeDatabaseApiResultInReverseOrder.result[1].id}`,
  );
});

test('Should fetch the search keyword when total count exceeds initial options', async () => {
  fetchMock.get(
    databaseApiRoute,
    {
      ...fakeDatabaseApiResult,
      count: fakeDatabaseApiResult.result.length + 1,
    },
    { overwriteRoutes: true },
  );

  const props = createProps();
  render(<DatabaseSelector {...props} />, { useRedux: true, store });
  const select = screen.getByRole('combobox', {
    name: 'Select database or type to search databases',
  });
  await waitFor(() =>
    expect(fetchMock.calls(databaseApiRoute)).toHaveLength(1),
  );
  expect(select).toBeInTheDocument();
  await userEvent.type(select, 'keywordtest');
  await waitFor(() =>
    expect(fetchMock.calls(databaseApiRoute)).toHaveLength(2),
  );
  expect(fetchMock.calls(databaseApiRoute)[1][0]).toContain('keywordtest');
});

test('should show empty state if there are no options', async () => {
  fetchMock.reset();
  fetchMock.get(databaseApiRoute, { result: [] });
  fetchMock.get(schemaApiRoute, { result: [] });
  fetchMock.get(tablesApiRoute, { result: [] });
  const props = createProps();
  render(
    <DatabaseSelector
      {...props}
      db={undefined}
      emptyState={<EmptyState size="small" title="empty" />}
    />,
    { useRedux: true, store },
  );
  const select = screen.getByRole('combobox', {
    name: 'Select database or type to search databases',
  });
  await userEvent.click(select);
  const emptystate = await screen.findByText('empty');
  expect(emptystate).toBeInTheDocument();
  expect(screen.queryByText('test-mysql')).not.toBeInTheDocument();
});

test('Should schema select display options', async () => {
  const props = createProps();
  render(<DatabaseSelector {...props} />, { useRedux: true, store });
  const select = screen.getByRole('combobox', {
    name: 'Select schema or type to search schemas: public',
  });
  expect(select).toBeInTheDocument();
  await userEvent.click(select);
  await waitFor(() => {
    expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
  });
  const publicOption = await screen.findByRole('option', { name: 'public' });
  expect(publicOption).toBeInTheDocument();

  const infoSchemaOption = await screen.findByRole('option', {
    name: 'information_schema',
  });
  expect(infoSchemaOption).toBeInTheDocument();
});

test('Sends the correct db when changing the database', async () => {
  const props = createProps();
  render(<DatabaseSelector {...props} />, { useRedux: true, store });
  const select = screen.getByRole('combobox', {
    name: 'Select database or type to search databases',
  });
  expect(select).toBeInTheDocument();
  await userEvent.click(select);
  await userEvent.click(await screen.findByText('test-mysql'));
  await waitFor(() =>
    expect(props.onDbChange).toHaveBeenCalledWith(
      expect.objectContaining({
        value: 2,
        database_name: 'test-mysql',
        backend: 'mysql',
      }),
    ),
  );
});

test('Sends the correct schema when changing the schema', async () => {
  const props = createProps();
  const { rerender } = render(<DatabaseSelector {...props} db={null} />, {
    useRedux: true,
    store,
  });
  await waitFor(() => expect(fetchMock.calls(databaseApiRoute).length).toBe(1));
  rerender(<DatabaseSelector {...props} />);
  expect(props.onSchemaChange).toHaveBeenCalledTimes(0);
  const select = screen.getByRole('combobox', {
    name: 'Select schema or type to search schemas: public',
  });
  expect(select).toBeInTheDocument();
  await userEvent.click(select);
  const schemaOption = await screen.findByText('information_schema');
  await userEvent.click(schemaOption);
  await waitFor(() =>
    expect(props.onSchemaChange).toHaveBeenCalledWith('information_schema'),
  );
  expect(props.onSchemaChange).toHaveBeenCalledTimes(1);
});
