/*!
 * 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.
 */

/* global jest, describe, test, expect, beforeEach, window */

import React from "react";
import { render, fireEvent } from "@testing-library/react";
import type { UseQueryResult } from "react-query";

import * as utils from "src/utils";
import * as useTaskLogModule from "src/api/useTaskLog";

import Logs from "./index";

const mockTaskLog = `
5d28cfda3219
*** Reading local file: /root/airflow/logs/dag_id=test_ui_grid/run_id=scheduled__2022-06-03T00:00:00+00:00/task_id=section_1.get_entry_group/attempt=1.log
[2022-06-04 00:00:01,901] {taskinstance.py:1132} INFO - Dependencies all met for <TaskInstance: test_ui_grid.section_1.get_entry_group scheduled__2022-06-03T00:00:00+00:00 [queued]>
[2022-06-04 00:00:01,906] {taskinstance.py:1132} INFO - Dependencies all met for <TaskInstance: test_ui_grid.section_1.get_entry_group scheduled__2022-06-03T00:00:00+00:00 [queued]>
[2022-06-04 00:00:01,906] {taskinstance.py:1329} INFO -
--------------------------------------------------------------------------------
[2022-06-04 00:00:01,906] {taskinstance.py:1330} INFO - Starting attempt 1 of 1
[2022-06-04 00:00:01,906] {taskinstance.py:1331} INFO -
--------------------------------------------------------------------------------
[2022-06-04 00:00:01,916] {taskinstance.py:1350} INFO - Executing <Task(BashOperator): section_1.get_entry_group> on 2022-06-03 00:00:00+00:00
[2022-06-04 00:00:01,919] {standard_task_runner.py:52} INFO - Started process 41646 to run task
[2022-06-04 00:00:01,920] {standard_task_runner.py:80} INFO - Running: ['***', 'tasks', 'run', 'test_ui_grid', 'section_1.get_entry_group', 'scheduled__2022-06-03T00:00:00+00:00', '--job-id', '1626', '--raw', '--subdir', 'DAGS_FOLDER/test_ui_grid.py', '--cfg-path', '/tmp/tmpte7k80ur']
[2022-06-04 00:00:01,921] {standard_task_runner.py:81} INFO - Job 1626: Subtask section_1.get_entry_group
[2022-06-04 00:00:01,921] {dagbag.py:507} INFO - Filling up the DagBag from /files/dags/test_ui_grid.py
[2022-06-04 00:00:01,964] {task_command.py:377} INFO - Running <TaskInstance: test_ui_grid.section_1.get_entry_group scheduled__2022-06-03T00:00:00+00:00 [running]> on host 5d28cfda3219
[2022-06-04 00:00:02,010] {taskinstance.py:1548} WARNING - Exporting env vars: AIRFLOW_CTX_DAG_OWNER=*** AIRFLOW_CTX_DAG_ID=test_ui_grid
`;

let useTaskLogMock: jest.SpyInstance;

describe("Test Logs Component.", () => {
  const returnValue = {
    data: mockTaskLog,
    isSuccess: true,
  } as UseQueryResult<string, unknown>;

  beforeEach(() => {
    useTaskLogMock = jest
      .spyOn(useTaskLogModule, "default")
      .mockImplementation(() => returnValue);
    window.HTMLElement.prototype.scrollIntoView = jest.fn();
  });

  test("Test Logs Content", () => {
    const tryNumber = 2;
    const { getByText } = render(
      <Logs
        dagId="dummyDagId"
        dagRunId="dummyDagRunId"
        taskId="dummyTaskId"
        executionDate="2020:01:01T01:00+00:00"
        tryNumber={tryNumber}
      />
    );
    expect(
      getByText("[2022-06-04, 00:00:01 UTC] {taskinstance.py:1329} INFO -", {
        exact: false,
      })
    ).toBeDefined();
    expect(
      getByText(
        "[2022-06-04, 00:00:01 UTC] {standard_task_runner.py:81} INFO - Job 1626: Subtask section_1.get_entry_group",
        { exact: false }
      )
    ).toBeDefined();
    expect(
      getByText("AIRFLOW_CTX_DAG_ID=test_ui_grid", { exact: false })
    ).toBeDefined();

    expect(useTaskLogMock).toHaveBeenLastCalledWith({
      dagId: "dummyDagId",
      dagRunId: "dummyDagRunId",
      taskId: "dummyTaskId",
      taskTryNumber: 2,
    });
  });

  test.each([
    { defaultWrap: "True", shouldBeChecked: true },
    { defaultWrap: "False", shouldBeChecked: false },
    { defaultWrap: "", shouldBeChecked: false },
  ])(
    "Test wrap checkbox initial value $defaultWrap",
    ({ defaultWrap, shouldBeChecked }) => {
      jest.spyOn(utils, "getMetaValue").mockImplementation((meta) => {
        if (meta === "default_wrap") return defaultWrap;
        return "";
      });

      const tryNumber = 2;
      const { getByTestId } = render(
        <Logs
          dagId="dummyDagId"
          dagRunId="dummyDagRunId"
          taskId="dummyTaskId"
          executionDate="2020:01:01T01:00+00:00"
          mapIndex={1}
          tryNumber={tryNumber}
        />
      );

      const wrapCheckbox = getByTestId("wrap-checkbox");
      if (shouldBeChecked) {
        expect(wrapCheckbox).toHaveAttribute("data-checked");
      } else {
        expect(wrapCheckbox.getAttribute("data-checked")).toBeNull();
      }
    }
  );

  test("Test Logs Content Mapped Task", () => {
    const tryNumber = 2;
    const { getByText } = render(
      <Logs
        dagId="dummyDagId"
        dagRunId="dummyDagRunId"
        taskId="dummyTaskId"
        executionDate="2020:01:01T01:00+00:00"
        mapIndex={1}
        tryNumber={tryNumber}
      />
    );
    expect(
      getByText("[2022-06-04, 00:00:01 UTC] {taskinstance.py:1329} INFO -", {
        exact: false,
      })
    ).toBeDefined();
    expect(
      getByText(
        "[2022-06-04, 00:00:01 UTC] {standard_task_runner.py:81} INFO - Job 1626: Subtask section_1.get_entry_group",
        { exact: false }
      )
    ).toBeDefined();
    expect(
      getByText("AIRFLOW_CTX_DAG_ID=test_ui_grid", { exact: false })
    ).toBeDefined();

    expect(useTaskLogMock).toHaveBeenLastCalledWith({
      dagId: "dummyDagId",
      dagRunId: "dummyDagRunId",
      mapIndex: 1,
      taskId: "dummyTaskId",
      taskTryNumber: 2,
    });
  });

  test("Test Logs Attempt Select Button", () => {
    const tryNumber = 2;
    const { getByText, getByTestId } = render(
      <Logs
        dagId="dummyDagId"
        dagRunId="dummyDagRunId"
        taskId="dummyTaskId"
        executionDate="2020:01:01T01:00+00:00"
        tryNumber={tryNumber}
      />
    );
    // Internal Log Attempt buttons.
    expect(getByText("1")).toBeDefined();
    expect(getByText("2")).toBeDefined();

    expect(getByText("Download")).toBeDefined();

    expect(useTaskLogMock).toHaveBeenLastCalledWith({
      dagId: "dummyDagId",
      dagRunId: "dummyDagRunId",
      taskId: "dummyTaskId",
      taskTryNumber: 2,
    });
    const attemptButton1 = getByTestId("log-attempt-select-button-1");

    fireEvent.click(attemptButton1);

    expect(useTaskLogMock).toHaveBeenLastCalledWith({
      dagId: "dummyDagId",
      dagRunId: "dummyDagRunId",
      taskId: "dummyTaskId",
      taskTryNumber: 1,
    });
  });
});
