""" :mod: OperationTests
    ====================

    .. module: OperationTests
    :synopsis: Operation test cases
    .. moduleauthor:: Krzysztof.Ciba@NOSPAMgmail.com

    Operation test cases
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

__RCSID__ = "$Id $"

import pytest

from DIRAC.RequestManagementSystem.Client.File import File
from DIRAC.RequestManagementSystem.Client.Operation import Operation


def test_ctor():
  """ test constructors and (de)serialisation """
  assert isinstance(Operation(), Operation), "empty ctor failed"

  # # using fromDict
  fromDict = {
      "Type": "replicateAndRegister",
      "TargetSE": "CERN-USER,PIC-USER",
      "SourceSE": None,
  }
  operation = Operation(fromDict)
  assert isinstance(operation, Operation), "fromDict ctor failed"
  for key, value in fromDict.items():
    assert getattr(operation, key) == value, "wrong attr value %s (%s) %s" % (key, getattr(operation, key), value)

  # # same with file
  operation = Operation(fromDict)
  operation.addFile(File({
      "LFN": "/lhcb/user/c/cibak/testFile",
      "Checksum": "1234567",
      "ChecksumType": "ADLER32",
      "Size": 1024,
      "Status": "Waiting",
  }))

  for key, value in fromDict.items():
    assert getattr(operation, key) == value, "wrong attr value %s (%s) %s" % (key, getattr(operation, key), value)

  toJSON = operation.toJSON()
  assert toJSON["OK"], "JSON serialization failed"


def test_valid_properties():
  operation = Operation()

  operation.Arguments = "foobar"
  assert operation.Arguments == b"foobar", "wrong Arguments"

  operation.SourceSE = "CERN-RAW"
  assert operation.SourceSE == "CERN-RAW", "wrong SourceSE"

  operation.TargetSE = "CERN-RAW"
  assert operation.TargetSE == "CERN-RAW", "wrong TargetSE"

  operation.Catalog = ""
  assert operation.Catalog == "", "wrong Catalog"

  operation.Catalog = "BookkeepingDB"
  assert operation.Catalog == "BookkeepingDB", "wrong Catalog"

  operation.Error = "error"
  assert operation.Error == "error", "wrong Error"

  toJSON = operation.toJSON()
  assert toJSON["OK"]


def test_StateMachine():
  """ state machine """
  op = Operation()
  assert op.Status == "Queued", "1. wrong status %s" % op.Status

  op.addFile(File({"Status": "Waiting"}))
  assert op.Status == "Queued", "2. wrong status %s" % op.Status

  op.addFile(File({"Status": "Scheduled"}))
  assert op.Status == "Scheduled", "3. wrong status %s" % op.Status

  op.addFile(File({"Status": "Done"}))
  assert op.Status == "Scheduled", "4. wrong status %s" % op.Status

  op.addFile(File({"Status": "Failed"}))
  assert op.Status == "Scheduled", "5. wrong status %s" % op.Status

  op[3].Status = "Scheduled"
  assert op.Status == "Scheduled", "6. wrong status %s" % op.Status

  op[0].Status = "Scheduled"
  assert op.Status == "Scheduled", "7. wrong status %s" % op.Status

  op[0].Status = "Waiting"
  assert op.Status == "Scheduled", "8. wrong status %s" % op.Status

  for f in op:
    f.Status = "Done"
  assert op.Status == "Done", "9. wrong status %s" % op.Status

  for f in op:
    f.Status = "Failed"
  assert op.Status == "Failed", "9. wrong status %s" % op.Status


def test_List():
  """ getitem, setitem, delitem and dirty """
  op = Operation()

  files = []
  for _ in range(5):
    f = File()
    files.append(f)
    op += f

  for i in range(len(op)):
    assert op[i] == files[i], "__getitem__ failed"

  for i in range(len(op)):
    op[i] = File({"LFN": "/%s" % i})
    assert op[i].LFN == "/%s" % i, "__setitem__ failed"

  del op[0]
  assert len(op) == 4, "__delitem__ failed"

  # opID set
  op.OperationID = 1
  del op[0]
