#!/usr/bin/env python
"""Test the hunt_view interface."""

from absl import app

from grr_response_server.gui import gui_test_lib
from grr.test_lib import test_lib


class TestHuntControl(gui_test_lib.GRRSeleniumHuntTest):
  """Test the hunt start/stop/delete functionality."""

  def testToolbarStateForStoppedHunt(self):
    hunt_id = self.CreateSampleHunt(stopped=True)

    self.Open("/legacy")
    self.WaitUntil(self.IsElementPresent, "client_query")
    self.Click("css=a[grrtarget=hunts]")
    self.WaitUntil(self.IsTextPresent, hunt_id)

    # Select a Hunt.
    self.Click("css=td:contains('%s')" % hunt_id)

    # Check we can now see the details.
    self.WaitUntil(self.IsElementPresent, "css=dl.dl-hunt")
    self.WaitUntil(self.IsTextPresent, "Clients Scheduled")
    self.WaitUntil(self.IsTextPresent, "Hunt ID")

    self.WaitUntil(
        self.IsElementPresent, "css=button[name=RunHunt]:not([disabled])"
    )
    self.WaitUntil(self.IsElementPresent, "css=button[name=StopHunt][disabled]")
    self.WaitUntil(
        self.IsElementPresent, "css=button[name=ModifyHunt]:not([disabled])"
    )

  def testToolbarStateForRunningHunt(self):
    hunt_id = self.CreateSampleHunt(stopped=False)

    self.Open("/legacy")
    self.WaitUntil(self.IsElementPresent, "client_query")
    self.Click("css=a[grrtarget=hunts]")
    self.WaitUntil(self.IsTextPresent, hunt_id)

    # Select a Hunt.
    self.Click("css=td:contains('%s')" % hunt_id)

    # Check we can now see the details.
    self.WaitUntil(self.IsElementPresent, "css=dl.dl-hunt")
    self.WaitUntil(self.IsTextPresent, "Clients Scheduled")
    self.WaitUntil(self.IsTextPresent, "Hunt ID")

    self.WaitUntil(self.IsElementPresent, "css=button[name=RunHunt][disabled]")
    self.WaitUntil(
        self.IsElementPresent, "css=button[name=StopHunt]:not([disabled])"
    )
    self.WaitUntil(
        self.IsElementPresent, "css=button[name=ModifyHunt][disabled]"
    )

  def testRunHunt(self):
    hunt_id = self.CreateSampleHunt(stopped=True)

    self.Open("/legacy")
    self.WaitUntil(self.IsElementPresent, "client_query")
    self.Click("css=a[grrtarget=hunts]")
    self.WaitUntil(self.IsTextPresent, hunt_id)

    # Select a Hunt.
    self.Click("css=td:contains('%s')" % hunt_id)

    # Click on Run button and check that dialog appears.
    self.Click("css=button[name=RunHunt]")
    self.WaitUntil(
        self.IsTextPresent, "Are you sure you want to run this hunt?"
    )

    # Click on "Proceed" and wait for authorization dialog to appear.
    self.Click("css=button[name=Proceed]")

    # This should be rejected now and a form request is made.
    self.WaitUntil(self.IsTextPresent, "Create a new approval")
    self.Click("css=grr-request-approval-dialog button[name=Cancel]")
    # Wait for dialog to disappear.
    self.WaitUntilNot(self.IsVisible, "css=.modal-open")

    self.RequestAndGrantHuntApproval(hunt_id)

    # Click on Run and wait for dialog again.
    self.Click("css=button[name=RunHunt]")
    self.WaitUntil(
        self.IsTextPresent, "Are you sure you want to run this hunt?"
    )

    # Click on "Proceed" and wait for success label to appear.
    # Also check that "Proceed" button gets disabled.
    self.Click("css=button[name=Proceed]")

    self.WaitUntil(self.IsTextPresent, "Hunt started successfully!")
    self.assertFalse(self.IsElementPresent("css=button[name=Proceed]"))

    # Click on "Cancel" and check that dialog disappears.
    self.Click("css=button[name=Close]")
    self.WaitUntilNot(self.IsVisible, "css=.modal-open")

    # View should be refreshed automatically.
    self.WaitUntil(self.IsTextPresent, "GenericHunt")
    # Check the hunt is in a running state.
    self.CheckState("STARTED")

  def testStopHunt(self):
    hunt_id = self.CreateSampleHunt(stopped=False)

    self.Open("/legacy")
    self.WaitUntil(self.IsElementPresent, "client_query")
    self.Click("css=a[grrtarget=hunts]")
    self.WaitUntil(self.IsTextPresent, hunt_id)

    # Select a Hunt.
    self.Click("css=td:contains('%s')" % hunt_id)

    # Click on Stop button and check that dialog appears.
    self.Click("css=button[name=StopHunt]")
    self.WaitUntil(
        self.IsTextPresent, "Are you sure you want to stop this hunt?"
    )

    # Click on "Proceed" and wait for authorization dialog to appear.
    self.Click("css=button[name=Proceed]")

    # This should be rejected now and a form request is made.
    self.WaitUntil(self.IsTextPresent, "Create a new approval")
    self.Click("css=grr-request-approval-dialog button[name=Cancel]")

    # Wait for dialog to disappear.
    self.WaitUntilNot(self.IsVisible, "css=.modal-open")

    self.RequestAndGrantHuntApproval(hunt_id)

    # Click on Stop and wait for dialog again.
    self.Click("css=button[name=StopHunt]")
    self.WaitUntil(
        self.IsTextPresent, "Are you sure you want to stop this hunt?"
    )

    # Click on "Proceed" and wait for success label to appear.
    # Also check that "Proceed" button gets disabled.
    self.Click("css=button[name=Proceed]")
    self.WaitUntil(self.IsTextPresent, "Hunt stopped successfully")
    self.assertFalse(self.IsElementPresent("css=button[name=Proceed]"))

    # Click on "Cancel" and check that dialog disappears.
    self.Click("css=button[name=Close]")
    self.WaitUntilNot(self.IsVisible, "css=.modal-open")

    # View should be refreshed automatically.
    self.WaitUntil(self.IsTextPresent, "GenericHunt")

    # Check the hunt is not in a running state.
    self.CheckState("STOPPED")

  def testModifyHunt(self):
    hunt_id = self.CreateSampleHunt(stopped=True)

    self.Open("/legacy")
    self.WaitUntil(self.IsElementPresent, "client_query")
    self.Click("css=a[grrtarget=hunts]")
    self.WaitUntil(self.IsTextPresent, hunt_id)

    # Select a Hunt.
    self.Click("css=td:contains('%s')" % hunt_id)

    # Click on Modify button and check that dialog appears.
    self.Click("css=button[name=ModifyHunt]")
    self.WaitUntil(self.IsTextPresent, "Modify this hunt")

    self.Type(
        "css=grr-modify-hunt-dialog label:contains('Client limit') ~ * input",
        "4483",
    )
    self.Type(
        "css=grr-modify-hunt-dialog label:contains('Client rate') ~ * input",
        "42",
    )
    self.Type(
        "css=grr-modify-hunt-dialog label:contains('Duration') ~ * input",
        "1337s",
    )

    # Click on Proceed.
    self.Click("css=button[name=Proceed]")

    # This should be rejected now and a form request is made.
    self.WaitUntil(self.IsTextPresent, "Create a new approval")
    self.Click("css=grr-request-approval-dialog button[name=Cancel]")
    # Wait for dialog to disappear.
    self.WaitUntilNot(self.IsVisible, "css=.modal-open")

    # Now create an approval.
    self.RequestAndGrantHuntApproval(hunt_id)

    # Click on Modify button and check that dialog appears.
    self.Click("css=button[name=ModifyHunt]")
    self.WaitUntil(self.IsTextPresent, "Modify this hunt")

    self.Type(
        "css=grr-modify-hunt-dialog label:contains('Client limit') ~ * input",
        "4483",
    )
    self.Type(
        "css=grr-modify-hunt-dialog label:contains('Client rate') ~ * input",
        "42",
    )
    self.Type(
        "css=grr-modify-hunt-dialog label:contains('Duration') ~ * input",
        "1337s",
    )

    # Click on "Proceed" and wait for success label to appear.
    # Also check that "Proceed" button gets disabled.
    self.Click("css=button[name=Proceed]")

    self.WaitUntil(self.IsTextPresent, "Hunt modified successfully!")
    self.assertFalse(self.IsElementPresent("css=button[name=Proceed]"))

    # Click on "Cancel" and check that dialog disappears.
    self.Click("css=button[name=Close]")
    self.WaitUntilNot(self.IsVisible, "css=.modal-open")

    # View should be refreshed automatically.
    self.WaitUntil(self.IsTextPresent, hunt_id)
    self.WaitUntil(self.IsTextPresent, "4483")
    self.WaitUntil(self.IsTextPresent, "1337s")

  def testDeleteHunt(self):
    # This needs to be created by a different user so we can test the
    # approval dialog.
    hunt_id = self.CreateSampleHunt(stopped=True, creator="random user")

    self.Open("/legacy")
    self.WaitUntil(self.IsElementPresent, "client_query")
    self.Click("css=a[grrtarget=hunts]")
    self.WaitUntil(self.IsTextPresent, hunt_id)

    # Select a Hunt.
    self.Click("css=td:contains('%s')" % hunt_id)

    # Click on delete button.
    self.Click("css=button[name=DeleteHunt]")
    self.WaitUntil(self.IsTextPresent, "Delete this hunt")

    # Click on Proceed.
    self.Click("css=button[name=Proceed]")

    # This should be rejected now and a form request is made.
    self.WaitUntil(self.IsTextPresent, "Create a new approval")
    self.Click("css=grr-request-approval-dialog button[name=Cancel]")
    # Wait for dialog to disappear.
    self.WaitUntilNot(self.IsVisible, "css=.modal-open")

    # Now create an approval.
    self.RequestAndGrantHuntApproval(hunt_id)

    # Select a hunt again, as it's deselected after approval dialog
    # disappears. TODO(user): if this behavior is not convenient, fix it.
    self.Click("css=td:contains('%s')" % hunt_id)

    # Click on Delete button and check that dialog appears.
    self.Click("css=button[name=DeleteHunt]")
    self.WaitUntil(self.IsTextPresent, "Delete this hunt")

    # Click on "Proceed" and wait for success label to appear.
    # Also check that "Proceed" button gets disabled.
    self.Click("css=button[name=Proceed]")

    self.WaitUntil(self.IsTextPresent, "Hunt deleted successfully!")
    self.assertFalse(self.IsElementPresent("css=button[name=Proceed]"))

    # Click on "Cancel" and check that dialog disappears.
    self.Click("css=button[name=Close]")
    self.WaitUntilNot(self.IsVisible, "css=.modal-open")


if __name__ == "__main__":
  app.run(test_lib.main)
