# Copyright 2019 Google LLC
#
# Licensed 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.

"""API messages."""

import collections
import logging

from protorpc import message_types
from protorpc import messages
import pytz
from tradefed_cluster import api_messages
from tradefed_cluster.util import ndb_shim as ndb


from google.oauth2 import credentials
from google.oauth2 import service_account

from multitest_transport.plugins import base as plugins
from multitest_transport.models import build
from multitest_transport.models import event_log
from multitest_transport.models import ndb_models
from multitest_transport.models import sql_models
from multitest_transport.util import env
from multitest_transport.util import file_util
from multitest_transport.util import xts_result

_OAUTH2_CREDENTIALS_USERNAME = 'User Account'

_convert_func_map = {}


def Converter(from_cls, to_cls):
  """A decorator to register a message converter.

  Args:
    from_cls: a class to convert from.
    to_cls: a class to convert to.
  Returns:
    a decorator function.
  """
  def Decorator(func):
    _convert_func_map[(from_cls, to_cls)] = func
    return func
  return Decorator


def Convert(obj, to_cls, from_cls=None):
  """Converts an object to a given class.

  Args:
    obj: an object.
    to_cls: a class to convert to.
    from_cls: a class to convert from (optional).
  Returns:
    a converted object.
  Raises:
    ValueError: if there's no registered converter function.
  """
  if obj is None:
    return None
  from_cls = from_cls or type(obj)
  func = _convert_func_map.get((from_cls, to_cls))
  if not func:
    raise ValueError('no convert function for %s -> %s' % (from_cls, to_cls))
  return func(obj)


def ConvertList(lst, to_cls, from_cls=None):
  """Converts an object or a list objects to a given class.

  Args:
    lst: a list of objects.
    to_cls: a class to convert to.
    from_cls: a class to convert from (optional).
  Returns:
    a a list of conveted objects.
  """
  if lst is None:
    return None
  return [Convert(obj, to_cls, from_cls) for obj in lst]


def ConvertToKey(model_cls, id_):
  """Convert to a ndb.Key object.

  Args:
    model_cls: a model class.
    id_: an object ID.
  Returns:
    a ndb.Key object.
  """
  try:
    id_ = int(id_)
  except ValueError:
    pass
  return ndb.Key(model_cls, id_)


def ConvertToKeyOrNone(model_cls, id_):
  """Convert to a ndb.Key object or None.

  This returns None if id_ is None.

  Args:
    model_cls: a model class.
    id_: an object ID.
  Returns:
    a ndb.Key object.
  """
  if id_ is None:
    return None
  return ConvertToKey(model_cls, id_)


def ConvertToDeviceSpecs(run_target):
  """Convert a run target to device specs.

  Args:
    run_target: a run target.
  Returns:
    a list of device specs.
  """
  if not run_target:
    return []
  return ['device_serial:%s' % s for s in run_target.split(';')]


def _AddTimezone(datetime, timezone=pytz.UTC):
  """Adds timezone to an NDB datetime (which doesn't store timezone)."""
  if datetime:
    return datetime.replace(tzinfo=timezone)  


class AuthorizationInfo(messages.Message):
  """OAuth2 authorization information.

  Attributes:
    url: an authorization url.
    is_manual: a boolean value which tell us to start automatic or manual
      copy/paste flow
  """
  url = messages.StringField(1, required=True)
  is_manual = messages.BooleanField(2, required=True)


class SimpleMessage(messages.Message):
  """Simple string message."""
  value = messages.StringField(1, required=True)


class NameValuePair(messages.Message):
  """A generic name-value pair to store an option.

  Attributes:
    name: a name.
    value: a value.
  """
  name = messages.StringField(1, required=True)
  value = messages.StringField(2)


class NameMultiValuePair(messages.Message):
  """A generic name-multi value pair to store an option.

  Attributes:
    name: a name.
    values: a value.
  """
  name = messages.StringField(1, required=True)
  values = messages.StringField(2, repeated=True)


def ConvertNameValuePairs(pairs, to_cls):
  """Convert message and NDB model name-value(s) pairs."""
  is_multi = to_cls in (NameMultiValuePair, ndb_models.NameMultiValuePair)
  d = collections.OrderedDict()
  for pair in pairs:
    if pair.name in d:
      logging.warning('Duplicate key %s in %s', pair.name, pairs)
    if is_multi:
      d[pair.name] = to_cls(name=pair.name, values=pair.values)
    else:
      d[pair.name] = to_cls(name=pair.name, value=pair.value)
  return list(d.values())


def ConvertNameValuePairsToDict(pairs):
  """Convert message or NDB model name-value(s) pairs to dict."""
  d = collections.OrderedDict()
  for pair in pairs:
    d[pair.name] = pair.value
  return d


class FileSegment(messages.Message):
  """Partial file content."""
  offset = messages.IntegerField(1)
  length = messages.IntegerField(2)
  lines = messages.StringField(3, repeated=True)


@Converter(file_util.FileSegment, FileSegment)
def _FileSegmentConverter(obj):
  lines = [line.decode() for line in obj.lines]
  return FileSegment(offset=obj.offset, length=obj.length, lines=lines)


class EventLogEntry(messages.Message):
  """An event log entry."""
  create_time = message_types.DateTimeField(1, required=True)
  level = messages.EnumField(ndb_models.EventLogLevel, 2, required=True)
  message = messages.StringField(3, required=True)


@Converter(ndb_models.EventLogEntry, EventLogEntry)
def _EventLogEntryConverter(obj):
  return EventLogEntry(
      create_time=_AddTimezone(obj.create_time),
      level=obj.level,
      message=obj.message)


class TestResourceParameters(messages.Message):
  """Repeated properties of TestResourceObj and TestResourceDef."""
  decompress_files = messages.StringField(1, repeated=True)


@Converter(ndb_models.TestResourceParameters, TestResourceParameters)
def _TestResourceParametersConverter(obj):
  return TestResourceParameters(decompress_files=obj.decompress_files)


@Converter(TestResourceParameters, ndb_models.TestResourceParameters)
def _TestResourceParametersMessageConverter(msg):
  return ndb_models.TestResourceParameters(
      decompress_files=msg.decompress_files)


class TestResourceDef(messages.Message):
  """A test resource definition for a test."""
  name = messages.StringField(1, required=True)
  default_download_url = messages.StringField(2)
  test_resource_type = messages.EnumField(ndb_models.TestResourceType, 3)
  decompress = messages.BooleanField(4)
  decompress_dir = messages.StringField(5)
  mount_zip = messages.BooleanField(6)
  params = messages.MessageField(TestResourceParameters, 7)


@Converter(ndb_models.TestResourceDef, TestResourceDef)
def _TestResourceDefConverter(obj):
  return TestResourceDef(
      name=obj.name,
      default_download_url=obj.default_download_url,
      test_resource_type=obj.test_resource_type,
      decompress=obj.decompress,
      decompress_dir=obj.decompress_dir,
      mount_zip=obj.mount_zip,
      params=Convert(obj.params, TestResourceParameters))


@Converter(TestResourceDef, ndb_models.TestResourceDef)
def _TestResourceDefMessageConverter(msg):
  return ndb_models.TestResourceDef(
      name=msg.name,
      default_download_url=msg.default_download_url,
      test_resource_type=msg.test_resource_type,
      decompress=msg.decompress,
      decompress_dir=msg.decompress_dir,
      mount_zip=msg.mount_zip,
      params=Convert(msg.params, ndb_models.TestResourceParameters))


class TestRunParameter(messages.Message):
  """Test run paramerer."""
  max_retry_on_test_failures = messages.IntegerField(1)
  invocation_timeout_seconds = messages.IntegerField(2)
  output_idle_timeout_seconds = messages.IntegerField(3)


@Converter(ndb_models.TestRunParameter, TestRunParameter)
def _TestRunParameterConverter(obj):
  return TestRunParameter(
      max_retry_on_test_failures=obj.max_retry_on_test_failures,
      output_idle_timeout_seconds=obj.output_idle_timeout_seconds)


@Converter(TestRunParameter, ndb_models.TestRunParameter)
def _TestRunParameterMessageConverter(msg):
  return ndb_models.TestRunParameter(
      max_retry_on_test_failures=msg.max_retry_on_test_failures,
      output_idle_timeout_seconds=msg.output_idle_timeout_seconds)


class Test(messages.Message):
  """A test."""
  id = messages.StringField(1)
  name = messages.StringField(2, required=True)
  description = messages.StringField(3)
  test_resource_defs = messages.MessageField(TestResourceDef, 4, repeated=True)
  command = messages.StringField(5)
  env_vars = messages.MessageField(NameValuePair, 6, repeated=True)
  output_file_patterns = messages.StringField(7, repeated=True)
  result_file = messages.StringField(8)
  setup_scripts = messages.StringField(9, repeated=True)
  jvm_options = messages.StringField(10, repeated=True)
  java_properties = messages.MessageField(NameValuePair, 11, repeated=True)
  context_file_dir = messages.StringField(12)
  context_file_pattern = messages.StringField(13)
  retry_command_line = messages.StringField(14)
  runner_sharding_args = messages.StringField(15)
  default_test_run_parameters = messages.MessageField(TestRunParameter, 16)
  module_config_pattern = messages.StringField(17)
  module_execution_args = messages.StringField(18)
  visibility_type = messages.EnumField(
      ndb_models.VisibilityType, 19, default=ndb_models.VisibilityType.PUBLIC
  )
  upload_file_patterns = messages.StringField(20, repeated=True)
  use_dynamic_download_mcts = messages.BooleanField(21)


@Converter(ndb_models.Test, Test)
def _TestConverter(obj):
  return Test(
      id=str(obj.key.id()) if obj.key else None,
      name=obj.name,
      description=obj.description,
      test_resource_defs=ConvertList(obj.test_resource_defs, TestResourceDef),
      command=obj.command,
      env_vars=ConvertNameValuePairs(obj.env_vars, NameValuePair),
      output_file_patterns=obj.output_file_patterns,
      result_file=obj.result_file,
      setup_scripts=obj.setup_scripts,
      jvm_options=obj.jvm_options,
      java_properties=ConvertNameValuePairs(obj.java_properties, NameValuePair),
      context_file_dir=obj.context_file_dir,
      context_file_pattern=obj.context_file_pattern,
      retry_command_line=obj.retry_command_line,
      runner_sharding_args=obj.runner_sharding_args,
      default_test_run_parameters=Convert(
          obj.default_test_run_parameters, TestRunParameter
      ),
      module_config_pattern=obj.module_config_pattern,
      module_execution_args=obj.module_execution_args,
      visibility_type=obj.visibility_type,
      upload_file_patterns=obj.upload_file_patterns,
      use_dynamic_download_mcts=obj.use_dynamic_download_mcts,
  )


@Converter(Test, ndb_models.Test)
def _TestMessageConverter(msg):
  return ndb_models.Test(
      key=ConvertToKeyOrNone(ndb_models.Test, msg.id),
      name=msg.name,
      description=msg.description,
      test_resource_defs=ConvertList(
          msg.test_resource_defs, ndb_models.TestResourceDef
      ),
      command=msg.command,
      env_vars=ConvertNameValuePairs(msg.env_vars, ndb_models.NameValuePair),
      setup_scripts=msg.setup_scripts,
      output_file_patterns=msg.output_file_patterns,
      result_file=msg.result_file,
      jvm_options=msg.jvm_options,
      java_properties=ConvertNameValuePairs(
          msg.java_properties, ndb_models.NameValuePair
      ),
      context_file_dir=msg.context_file_dir,
      context_file_pattern=msg.context_file_pattern,
      retry_command_line=msg.retry_command_line,
      runner_sharding_args=msg.runner_sharding_args,
      default_test_run_parameters=Convert(
          msg.default_test_run_parameters, ndb_models.TestRunParameter
      ),
      module_config_pattern=msg.module_config_pattern,
      module_execution_args=msg.module_execution_args,
      visibility_type=msg.visibility_type,
      upload_file_patterns=msg.upload_file_patterns,
      use_dynamic_download_mcts=msg.use_dynamic_download_mcts,
  )


class TestList(messages.Message):
  """A list of tests."""
  tests = messages.MessageField(Test, 1, repeated=True)


class CredentialsInfo(messages.Message):
  """Credentials info object."""
  email = messages.StringField(1)


@Converter(credentials.Credentials, CredentialsInfo)
def _OauthCredentialsConverter(_):
  # TODO: Get email from userinfo endpoint
  return CredentialsInfo(
      email=_OAUTH2_CREDENTIALS_USERNAME)


@Converter(service_account.Credentials, CredentialsInfo)
def _ServiceAccountCredentialsConverter(obj):
  return CredentialsInfo(
      email=obj.service_account_email)


class BuildChannelConfig(messages.Message):
  """A build channel configuration."""
  id = messages.StringField(1)
  name = messages.StringField(2, required=True)
  provider_name = messages.StringField(3, required=True)
  options = messages.MessageField(NameValuePair, 4, repeated=True)


@Converter(ndb_models.BuildChannelConfig, BuildChannelConfig)
def _BuildChannelConfigConverter(obj):
  return BuildChannelConfig(
      id=str(obj.key.id()) if obj.key else None,
      name=obj.name,
      provider_name=obj.provider_name,
      options=ConvertNameValuePairs(obj.options, NameValuePair))


@Converter(BuildChannelConfig, ndb_models.BuildChannelConfig)
def _BuildChannelConfigMessageConverter(msg):
  return ndb_models.BuildChannelConfig(
      key=ConvertToKeyOrNone(ndb_models.BuildChannelConfig, msg.id),
      name=msg.name,
      provider_name=msg.provider_name,
      options=ConvertNameValuePairs(msg.options, ndb_models.NameValuePair))


class BuildChannel(messages.Message):
  """A build channel, which combines channel config and provider properties."""
  id = messages.StringField(1, required=True)
  name = messages.StringField(2, required=True)
  provider_name = messages.StringField(3, required=True)
  auth_state = messages.EnumField(
      ndb_models.AuthorizationState, 4, required=True)
  auth_methods = messages.EnumField(
      ndb_models.AuthorizationMethod, 5, repeated=True)
  credentials = messages.MessageField(CredentialsInfo, 6)
  build_item_path_type = messages.EnumField(
      ndb_models.BuildItemPathType, 7, required=True)


@Converter(build.BuildChannel, BuildChannel)
def _BuildChannelConverter(obj):
  return BuildChannel(
      id=str(obj.id),
      name=obj.name,
      provider_name=obj.provider_name,
      auth_state=obj.auth_state,
      auth_methods=obj.auth_methods,
      credentials=Convert(obj.credentials, CredentialsInfo),
      build_item_path_type=obj.build_item_path_type)


class BuildChannelList(messages.Message):
  """A list of build channels."""
  build_channels = messages.MessageField(BuildChannel, 1, repeated=True)


class OptionDef(messages.Message):
  """A plugin option definition."""
  name = messages.StringField(1, required=True)
  value_type = messages.StringField(2, required=True)
  choices = messages.StringField(3, repeated=True)
  default = messages.StringField(4)


@Converter(plugins.OptionDef, OptionDef)
def _OptionDefConverter(obj):
  return OptionDef(
      name=obj.name,
      value_type=obj.value_type.__name__,
      choices=obj.choices or [],
      default=obj.default)


class BuildChannelProvider(messages.Message):
  """Information about a build channel provider."""
  name = messages.StringField(1, required=True)
  option_defs = messages.MessageField(OptionDef, 2, repeated=True)


class BuildChannelProviderList(messages.Message):
  """A list of build channel providers."""
  build_channel_providers = messages.MessageField(
      BuildChannelProvider, 1, repeated=True)


class BuildItem(messages.Message):
  """A build item."""
  name = messages.StringField(1)
  path = messages.StringField(2)
  is_file = messages.BooleanField(3)
  size = messages.IntegerField(4)
  timestamp = message_types.DateTimeField(5)
  description = messages.StringField(6)


@Converter(plugins.BuildItem, BuildItem)
def _BuildItemConverter(obj):
  return BuildItem(
      name=obj.name,
      path=obj.path,
      is_file=obj.is_file,
      size=obj.size,
      timestamp=obj.timestamp,
      description=obj.description)


class BuildItemList(messages.Message):
  """A list of build items."""
  build_items = messages.MessageField(BuildItem, 1, repeated=True)
  next_page_token = messages.StringField(2)


class TradefedConfigObject(messages.Message):
  class_name = messages.StringField(1, required=True)
  option_values = messages.MessageField(NameMultiValuePair, 2, repeated=True)


@Converter(ndb_models.TradefedConfigObject, TradefedConfigObject)
def _TradefedConfigObjectConverter(obj):
  return TradefedConfigObject(
      class_name=obj.class_name,
      option_values=ConvertNameValuePairs(
          obj.option_values, NameMultiValuePair))


@Converter(TradefedConfigObject, ndb_models.TradefedConfigObject)
def _TradefedConfigObjectMessageConverter(msg):
  return ndb_models.TradefedConfigObject(
      class_name=msg.class_name,
      option_values=ConvertNameValuePairs(
          msg.option_values, ndb_models.NameMultiValuePair))


class ConfigSetInfo(messages.Message):
  """Metadata for a config set."""
  url = messages.StringField(1, required=True)
  hash = messages.StringField(2)
  name = messages.StringField(3, required=True)
  description = messages.StringField(4)
  last_update_time = messages.StringField(5)
  status = messages.EnumField(ndb_models.ConfigSetStatus, 6)


@Converter(ndb_models.ConfigSetInfo, ConfigSetInfo)
def _ConfigSetInfoConverter(obj):
  return ConfigSetInfo(
      url=obj.url,
      hash=obj.hash,
      name=obj.name,
      description=obj.description,
      last_update_time=obj.last_update_time,
  )


@Converter(ConfigSetInfo, ndb_models.ConfigSetInfo)
def _ConfigSetInfoMessageConverter(msg):
  return ndb_models.ConfigSetInfo(
      key=ConvertToKeyOrNone(ndb_models.ConfigSetInfo, msg.url),
      url=msg.url,
      hash=msg.hash,
      name=msg.name,
      description=msg.description,
      last_update_time=msg.last_update_time,
  )


class ConfigSetInfoList(messages.Message):
  config_set_infos = messages.MessageField(ConfigSetInfo, 1, repeated=True)


@Converter(ndb_models.ConfigSetInfoList, ConfigSetInfoList)
def _ConfigSetInfoListConverter(obj):
  return ConfigSetInfoList(
      config_set_infos=ConvertList(obj.config_set_infos, ConfigSetInfo))


@Converter(ConfigSetInfoList, ndb_models.ConfigSetInfoList)
def _ConfigSetInfoListMessageConverter(msg):
  return ndb_models.ConfigSetInfoList(
      config_set_infos=ConvertList(
          msg.config_set_infos, ndb_models.ConfigSetInfo))


class DeviceAction(messages.Message):
  """A device action."""
  id = messages.StringField(1)
  name = messages.StringField(2, required=True)
  description = messages.StringField(3)
  test_resource_defs = messages.MessageField(TestResourceDef, 4, repeated=True)
  tradefed_target_preparers = messages.MessageField(
      TradefedConfigObject, 5, repeated=True)
  device_type = messages.StringField(6)
  tradefed_options = messages.MessageField(NameMultiValuePair, 7, repeated=True)
  device_spec = messages.StringField(8)


@Converter(ndb_models.DeviceAction, DeviceAction)
def _DeviceActionConverter(obj):
  return DeviceAction(
      id=str(obj.key.id()) if obj.key else None,
      name=obj.name,
      description=obj.description,
      test_resource_defs=ConvertList(obj.test_resource_defs, TestResourceDef),
      tradefed_target_preparers=ConvertList(
          obj.tradefed_target_preparers, TradefedConfigObject),
      device_type=obj.device_type,
      tradefed_options=ConvertNameValuePairs(
          obj.tradefed_options, NameMultiValuePair),
      device_spec=obj.device_spec)


@Converter(DeviceAction, ndb_models.DeviceAction)
def _DeviceActionMessageConverter(msg):
  return ndb_models.DeviceAction(
      key=ConvertToKeyOrNone(ndb_models.DeviceAction, msg.id),
      name=msg.name,
      description=msg.description,
      test_resource_defs=ConvertList(
          msg.test_resource_defs, ndb_models.TestResourceDef),
      tradefed_target_preparers=ConvertList(
          msg.tradefed_target_preparers, ndb_models.TradefedConfigObject),
      device_type=msg.device_type,
      tradefed_options=ConvertNameValuePairs(
          msg.tradefed_options, ndb_models.NameMultiValuePair),
      device_spec=msg.device_spec)


class DeviceActionList(messages.Message):
  """A list of device actions."""
  device_actions = messages.MessageField(DeviceAction, 1, repeated=True)


class TestModuleResult(messages.Message):
  """Test module result."""
  id = messages.StringField(1)  # Legacy test results will not have an ID
  name = messages.StringField(2, required=True)
  complete = messages.BooleanField(3, required=True)
  duration_ms = messages.IntegerField(4, required=True)
  passed_tests = messages.IntegerField(5, required=True)
  failed_tests = messages.IntegerField(6, required=True)
  total_tests = messages.IntegerField(7, required=True)
  error_message = messages.StringField(8)


@Converter(sql_models.TestModuleResult, TestModuleResult)
def _TestModuleResultConverter(obj):
  return TestModuleResult(
      id=obj.id,
      name=obj.name,
      complete=obj.complete,
      duration_ms=obj.duration_ms,
      passed_tests=obj.passed_tests,
      failed_tests=obj.failed_tests,
      total_tests=obj.total_tests,
      error_message=obj.error_message,
  )


@Converter(api_messages.TestGroupStatus, TestModuleResult)
def _LegacyTestModuleResultConverter(obj):
  return TestModuleResult(
      name=obj.name,
      complete=obj.is_complete,
      duration_ms=obj.elapsed_time,
      passed_tests=obj.passed_test_count,
      failed_tests=obj.failed_test_count,
      total_tests=obj.total_test_count,
      error_message=obj.failure_message,
  )


class TestModuleResultList(messages.Message):
  """List of test module results."""
  results = messages.MessageField(TestModuleResult, 1, repeated=True)
  extra_info = messages.StringField(2)


class TestCaseResult(messages.Message):
  """Test case result."""
  id = messages.IntegerField(1, required=True)
  module_id = messages.StringField(2, required=True)
  name = messages.StringField(3, required=True)
  status = messages.EnumField(xts_result.TestStatus, 4, required=True)
  error_message = messages.StringField(5)
  stack_trace = messages.StringField(6)


@Converter(sql_models.TestCaseResult, TestCaseResult)
def _TestCaseResultConverter(obj):
  return TestCaseResult(
      id=obj.id,
      module_id=obj.module_id,
      name=obj.name,
      status=obj.status,
      error_message=obj.error_message,
      stack_trace=obj.stack_trace,
  )


class TestCaseResultList(messages.Message):
  """List of test case results with pagination."""
  results = messages.MessageField(TestCaseResult, 1, repeated=True)
  next_page_token = messages.StringField(2)


class TestRunAction(messages.Message):
  """A test run action."""
  id = messages.StringField(1)
  name = messages.StringField(2, required=True)
  description = messages.StringField(3)
  hook_class_name = messages.StringField(4, required=True)
  phases = messages.EnumField(ndb_models.TestRunPhase, 5, repeated=True)
  options = messages.MessageField(NameValuePair, 6, repeated=True)
  tradefed_result_reporters = messages.MessageField(
      TradefedConfigObject, 7, repeated=True)
  authorization_state = messages.EnumField(ndb_models.AuthorizationState, 8)
  credentials = messages.MessageField(CredentialsInfo, 9)


@Converter(ndb_models.TestRunAction, TestRunAction)
def _TestRunActionConverter(obj):
  return TestRunAction(
      id=str(obj.key.id()) if obj.key else None,
      name=obj.name,
      description=obj.description,
      hook_class_name=obj.hook_class_name,
      phases=obj.phases,
      options=ConvertNameValuePairs(obj.options, NameValuePair),
      tradefed_result_reporters=ConvertList(
          obj.tradefed_result_reporters, TradefedConfigObject),
      credentials=Convert(obj.credentials, CredentialsInfo))


@Converter(TestRunAction, ndb_models.TestRunAction)
def _TestRunActionMessageConverter(msg):
  return ndb_models.TestRunAction(
      key=ConvertToKeyOrNone(ndb_models.TestRunAction, msg.id),
      name=msg.name,
      description=msg.description,
      hook_class_name=msg.hook_class_name,
      phases=msg.phases,
      options=ConvertNameValuePairs(msg.options, ndb_models.NameValuePair),
      tradefed_result_reporters=ConvertList(
          msg.tradefed_result_reporters, ndb_models.TradefedConfigObject))


class TestRunActionList(messages.Message):
  """A list of test run actions."""
  actions = messages.MessageField(TestRunAction, 1, repeated=True)


class TestRunActionRef(messages.Message):
  """A test run action reference."""
  action_id = messages.StringField(1)
  options = messages.MessageField(NameValuePair, 2, repeated=True)


@Converter(ndb_models.TestRunActionRef, TestRunActionRef)
def _TestRunActionRefConverter(obj):
  return TestRunActionRef(
      action_id=str(obj.action_key.id()) if obj.action_key else None,
      options=ConvertNameValuePairs(obj.options, NameValuePair))


@Converter(TestRunActionRef, ndb_models.TestRunActionRef)
def _TestRunActionRefMessageConverter(msg):
  return ndb_models.TestRunActionRef(
      action_key=ConvertToKeyOrNone(ndb_models.TestRunAction, msg.action_id),
      options=ConvertNameValuePairs(msg.options, ndb_models.NameValuePair))


class TestRunActionRefList(messages.Message):
  """A list of test run action references."""
  refs = messages.MessageField(TestRunActionRef, 1, repeated=True)


class TestRunHook(messages.Message):
  """Information about a test run hook."""
  name = messages.StringField(1, required=True)
  option_defs = messages.MessageField(OptionDef, 2, repeated=True)


class TestRunHookList(messages.Message):
  """A list of test run hook."""
  test_run_hooks = messages.MessageField(TestRunHook, 1, repeated=True)


class TestResourceObj(messages.Message):
  """A test resource object for a test."""
  name = messages.StringField(1)
  url = messages.StringField(2)
  cache_url = messages.StringField(3)
  test_resource_type = messages.EnumField(ndb_models.TestResourceType, 4)
  decompress = messages.BooleanField(5)
  decompress_dir = messages.StringField(6)
  mount_zip = messages.BooleanField(7)
  params = messages.MessageField(TestResourceParameters, 8)


@Converter(ndb_models.TestResourceObj, TestResourceObj)
def _TestResourceObjConverter(obj):
  return TestResourceObj(
      name=obj.name,
      url=obj.url,
      cache_url=obj.cache_url,
      test_resource_type=obj.test_resource_type,
      decompress=obj.decompress,
      decompress_dir=obj.decompress_dir,
      mount_zip=obj.mount_zip,
      params=Convert(obj.params, TestResourceParameters))


@Converter(TestResourceObj, ndb_models.TestResourceObj)
def _TestResourceObjMessageConverter(msg):
  return ndb_models.TestResourceObj(
      name=msg.name,
      url=msg.url,
      cache_url=msg.cache_url,
      test_resource_type=msg.test_resource_type,
      decompress=msg.decompress,
      decompress_dir=msg.decompress_dir,
      mount_zip=msg.mount_zip,
      params=Convert(msg.params, ndb_models.TestResourceParameters))


class TestRunConfig(messages.Message):
  """A test run config."""
  test_id = messages.StringField(1, required=True)
  cluster = messages.StringField(
      2, required=True, default=ndb_models.DEFAULT_CLUSTER
  )
  command = messages.StringField(3, required=True, default='')
  retry_command = messages.StringField(4, required=True, default='')
  device_specs = messages.StringField(5, repeated=True)
  run_target = messages.StringField(6)  # Deprecated
  run_count = messages.IntegerField(7, required=True, default=1)
  shard_count = messages.IntegerField(8, required=True, default=1)
  sharding_mode = messages.EnumField(
      ndb_models.ShardingMode, 9, default=ndb_models.ShardingMode.RUNNER)
  extra_args = messages.StringField(10)  # TODO: Deprecated
  retry_extra_args = messages.StringField(11)  # TODO: Deprecated
  max_retry_on_test_failures = messages.IntegerField(12)
  queue_timeout_seconds = messages.IntegerField(
      13, required=True, default=env.DEFAULT_QUEUE_TIMEOUT_SECONDS)
  invocation_timeout_seconds = messages.IntegerField(
      14, required=True, default=env.DEFAULT_INVOCATION_TIMEOUT_SECONDS)
  output_idle_timeout_seconds = messages.IntegerField(
      15, default=env.DEFAULT_OUTPUT_IDLE_TIMEOUT_SECONDS)
  before_device_action_ids = messages.StringField(16, repeated=True)
  test_run_action_refs = messages.MessageField(
      TestRunActionRef, 17, repeated=True)
  test_resource_objs = messages.MessageField(
      TestResourceObj, 18, repeated=True)
  use_parallel_setup = messages.BooleanField(19, default=True)
  allow_partial_device_match = messages.BooleanField(20, default=False)


@Converter(ndb_models.TestRunConfig, TestRunConfig)
def _TestRunConfigConverter(obj):
  """Converts test run configs."""
  if (not obj.command or not obj.retry_command) and obj.test_key:
    test = obj.test_key.get()
    if not obj.command and test:
      obj.command = test.command
      if obj.extra_args:
        obj.command += ' %s' % obj.extra_args
    if not obj.retry_command and test:
      obj.retry_command = test.retry_command_line
      if obj.retry_extra_args:
        obj.retry_command += ' %s' % obj.retry_extra_args
  return TestRunConfig(
      test_id=str(obj.test_key.id()) if obj.test_key else None,
      cluster=obj.cluster,
      command=obj.command,
      retry_command=obj.retry_command,
      device_specs=obj.device_specs or ConvertToDeviceSpecs(obj.run_target),
      run_target=obj.run_target,
      run_count=obj.run_count,
      shard_count=obj.shard_count,
      sharding_mode=obj.sharding_mode,
      max_retry_on_test_failures=obj.max_retry_on_test_failures,
      queue_timeout_seconds=obj.queue_timeout_seconds,
      invocation_timeout_seconds=obj.invocation_timeout_seconds,
      output_idle_timeout_seconds=obj.output_idle_timeout_seconds,
      before_device_action_ids=[
          str(key.id()) for key in obj.before_device_action_keys
      ],
      test_run_action_refs=ConvertList(
          obj.test_run_action_refs, TestRunActionRef),
      test_resource_objs=ConvertList(obj.test_resource_objs, TestResourceObj),
      use_parallel_setup=obj.use_parallel_setup,
      allow_partial_device_match=obj.allow_partial_device_match)


@Converter(TestRunConfig, ndb_models.TestRunConfig)
def _TestRunConfigMessageConverter(msg):
  return ndb_models.TestRunConfig(
      test_key=ConvertToKeyOrNone(ndb_models.Test, msg.test_id),
      cluster=msg.cluster,
      command=msg.command,
      retry_command=msg.retry_command,
      device_specs=msg.device_specs,
      run_target=msg.run_target,
      run_count=msg.run_count,
      shard_count=msg.shard_count,
      sharding_mode=msg.sharding_mode,
      extra_args=msg.extra_args,  # TODO: Deprecated
      retry_extra_args=msg.retry_extra_args,  # TODO: Deprecated
      max_retry_on_test_failures=msg.max_retry_on_test_failures,
      queue_timeout_seconds=msg.queue_timeout_seconds,
      invocation_timeout_seconds=msg.invocation_timeout_seconds,
      output_idle_timeout_seconds=msg.output_idle_timeout_seconds,
      before_device_action_keys=[
          ConvertToKeyOrNone(ndb_models.DeviceAction, device_action_id)
          for device_action_id in msg.before_device_action_ids
      ],
      test_run_action_refs=ConvertList(
          msg.test_run_action_refs, ndb_models.TestRunActionRef),
      test_resource_objs=ConvertList(
          msg.test_resource_objs, ndb_models.TestResourceObj),
      use_parallel_setup=msg.use_parallel_setup,
      allow_partial_device_match=msg.allow_partial_device_match)


class TestRunConfigList(messages.Message):
  """A list of test run configs."""
  test_run_configs = messages.MessageField(TestRunConfig, 1, repeated=True)


@Converter(ndb_models.TestRunConfigList, TestRunConfigList)
def _TestRunConfigListConverter(obj):
  return TestRunConfigList(
      test_run_configs=ConvertList(obj.test_run_configs, TestRunConfig),)


@Converter(TestRunConfigList, ndb_models.TestRunConfigList)
def _TestRunConfigListMessageConverter(msg):
  return ndb_models.TestRunConfigList(
      test_run_configs=ConvertList(msg.test_run_configs,
                                   ndb_models.TestRunConfig))


# TODO: Deprecate TestResourcePipe
class TestResourcePipe(messages.Message):
  """A test resource pipe for a test plan."""
  name = messages.StringField(1, required=True)
  url = messages.StringField(2)
  test_resource_type = messages.EnumField(ndb_models.TestResourceType, 3)


@Converter(ndb_models.TestResourcePipe, TestResourcePipe)
def _TestResourcePipeConverter(obj):
  return TestResourcePipe(
      name=obj.name,
      url=obj.url,
      test_resource_type=obj.test_resource_type)


@Converter(TestResourcePipe, ndb_models.TestResourcePipe)
def _TestResourcePipeMessageConverter(msg):
  return ndb_models.TestResourcePipe(
      name=msg.name,
      url=msg.url,
      test_resource_type=msg.test_resource_type)


class TestRunSequence(messages.Message):
  """A list of test run configs to run as retries."""
  id = messages.StringField(1)
  state = messages.EnumField(ndb_models.TestRunSequenceState, 2)
  test_run_configs = messages.MessageField(TestRunConfig, 3, repeated=True)
  finished_test_run_ids = messages.StringField(4, repeated=True)


@Converter(ndb_models.TestRunSequence, TestRunSequence)
def _TestRunSequenceConverter(obj):
  return TestRunSequence(
      id=str(obj.key.id()),
      state=obj.state,
      test_run_configs=ConvertList(obj.test_run_configs, TestRunConfig),
      finished_test_run_ids=obj.finished_test_run_ids)


@Converter(TestRunSequence, ndb_models.TestRunSequence)
def _TestRunSequenceMessageConverter(msg):
  return ndb_models.TestRunSequence(
      state=msg.state,
      test_run_configs=ConvertList(msg.test_run_configs,
                                   ndb_models.TestRunConfig),
      finished_test_run_ids=msg.finished_test_run_ids)


class TestPlan(messages.Message):
  """A test plan."""
  id = messages.StringField(1)
  name = messages.StringField(2, required=True)
  labels = messages.StringField(3, repeated=True)
  cron_exp = messages.StringField(4)
  cron_exp_timezone = messages.StringField(5, default='UTC')
  test_run_configs = messages.MessageField(TestRunConfig, 6, repeated=True)
  test_run_sequences = messages.MessageField(
      TestRunConfigList, 7, repeated=True)
  last_run_time = message_types.DateTimeField(8)
  last_run_ids = messages.StringField(9, repeated=True)
  last_run_error = messages.StringField(10)
  next_run_time = message_types.DateTimeField(11)


@Converter(ndb_models.TestPlan, TestPlan)
def _TestPlanConverter(obj):
  status = None
  if obj.key.id():
    status = ndb_models.TestPlanStatus.query(ancestor=obj.key).get()
  return TestPlan(
      id=str(obj.key.id()),
      name=obj.name,
      labels=obj.labels,
      cron_exp=obj.cron_exp,
      cron_exp_timezone=obj.cron_exp_timezone,
      test_run_configs=ConvertList(obj.test_run_configs, TestRunConfig),
      test_run_sequences=ConvertList(obj.test_run_sequences, TestRunConfigList),
      last_run_time=_AddTimezone(status.last_run_time) if status else None,
      last_run_ids=([str(key.id()) for key in status.last_run_keys]
                    if status else []),
      last_run_error=status.last_run_error if status else None,
      next_run_time=_AddTimezone(status.next_run_time) if status else None,
  )


@Converter(TestPlan, ndb_models.TestPlan)
def _TestPlanMessageConverter(msg):
  return ndb_models.TestPlan(
      key=ConvertToKeyOrNone(ndb_models.TestPlan, getattr(msg, 'id')),
      name=msg.name,
      labels=msg.labels,
      cron_exp=msg.cron_exp,
      cron_exp_timezone=msg.cron_exp_timezone,
      test_run_configs=ConvertList(
          msg.test_run_configs, ndb_models.TestRunConfig),
      test_run_sequences=ConvertList(
          msg.test_run_sequences, ndb_models.TestRunConfigList))


class TestPlanList(messages.Message):
  """A list of test plans."""
  test_plans = messages.MessageField(TestPlan, 1, repeated=True)


class TestContextObj(messages.Message):
  """A test context object."""
  command_line = messages.StringField(1)
  env_vars = messages.MessageField(NameValuePair, 2, repeated=True)
  test_resources = messages.MessageField(TestResourceObj, 3, repeated=True)


@Converter(ndb_models.TestContextObj, TestContextObj)
def _TestContextObjConverter(obj):
  return TestContextObj(
      command_line=obj.command_line,
      env_vars=ConvertNameValuePairs(obj.env_vars, NameValuePair),
      test_resources=ConvertList(obj.test_resources, TestResourceObj))


class TestPackageInfo(messages.Message):
  """A test package info."""
  build_number = messages.StringField(1)
  target_architecture = messages.StringField(2)
  name = messages.StringField(3)
  fullname = messages.StringField(4)
  version = messages.StringField(5)


@Converter(ndb_models.TestPackageInfo, TestPackageInfo)
def _TestPackageInfoConverter(obj):
  return TestPackageInfo(
      build_number=obj.build_number,
      target_architecture=obj.target_architecture,
      name=obj.name,
      fullname=obj.fullname,
      version=obj.version)


class TestDeviceInfo(messages.Message):
  """A test device info."""
  device_serial = messages.StringField(1)
  hostname = messages.StringField(2)
  run_target = messages.StringField(3)
  build_id = messages.StringField(4)
  product = messages.StringField(5)
  sdk_version = messages.StringField(7)


@Converter(ndb_models.TestDeviceInfo, TestDeviceInfo)
def _TestDeviceInfoConverter(obj):
  return TestDeviceInfo(
      device_serial=obj.device_serial,
      hostname=obj.hostname,
      run_target=obj.run_target,
      build_id=obj.build_id,
      product=obj.product,
      sdk_version=obj.sdk_version)


class TestRun(messages.Message):
  """A test run."""
  id = messages.StringField(1)
  prev_test_run_id = messages.StringField(2)
  user = messages.StringField(3)
  labels = messages.StringField(4, repeated=True)
  test_plan = messages.MessageField(TestPlan, 5)
  test = messages.MessageField(Test, 6)
  test_run_config = messages.MessageField(TestRunConfig, 7)
  test_resources = messages.MessageField(TestResourceObj, 8, repeated=True)
  state = messages.EnumField(ndb_models.TestRunState, 9)
  state_info = messages.StringField(10)
  output_url = messages.StringField(11)
  prev_test_context = messages.MessageField(TestContextObj, 12)
  next_test_context = messages.MessageField(TestContextObj, 13)

  request_id = messages.StringField(14)
  sequence_id = messages.StringField(15)
  total_test_count = messages.IntegerField(16)
  failed_test_count = messages.IntegerField(17)
  failed_test_run_count = messages.IntegerField(18)

  create_time = message_types.DateTimeField(19)
  update_time = message_types.DateTimeField(20)

  before_device_actions = messages.MessageField(DeviceAction, 21, repeated=True)
  test_run_actions = messages.MessageField(TestRunAction, 22, repeated=True)

  test_devices = messages.MessageField(TestDeviceInfo, 23, repeated=True)
  test_package_info = messages.MessageField(TestPackageInfo, 24)
  log_entries = messages.MessageField(EventLogEntry, 25, repeated=True)


@Converter(ndb_models.TestRun, TestRun)
def _TestRunConverter(obj):
  """Converts a ndb_models.TestRun object to a message."""
  # TestRun.test stores a snapshot copy of a test at test run creation time.
  test_msg = Convert(obj.test, Test)
  test_run_config_msg = Convert(obj.test_run_config, TestRunConfig)
  # Grab a valid test id from test_run_config since a snapshot copy is missing
  # a key.
  if test_msg and test_run_config_msg:
    test_msg.id = test_run_config_msg.test_id

  return TestRun(
      id=str(obj.key.id()),
      prev_test_run_id=(str(obj.prev_test_run_key.id())
                        if obj.prev_test_run_key else None),
      user=obj.user,
      labels=obj.labels,
      test_plan=(
          Convert(obj.test_plan_key.get(), TestPlan)
          if obj.test_plan_key else None),
      test=test_msg,
      test_run_config=test_run_config_msg,
      test_resources=ConvertList(obj.test_resources, TestResourceObj),
      state=obj.state,
      state_info=_GetTestRunStateInfo(obj),
      output_url=(file_util.GetAppStorageUrl([obj.output_path])
                  if obj.output_path else None),
      prev_test_context=Convert(obj.prev_test_context, TestContextObj),
      next_test_context=Convert(obj.next_test_context, TestContextObj),
      request_id=obj.request_id,
      sequence_id=obj.sequence_id,
      total_test_count=obj.total_test_count,
      failed_test_count=obj.failed_test_count,
      failed_test_run_count=obj.failed_test_run_count,
      create_time=_AddTimezone(obj.create_time),
      update_time=_AddTimezone(obj.update_time),
      before_device_actions=ConvertList(
          obj.before_device_actions, DeviceAction),
      test_run_actions=ConvertList(obj.test_run_actions, TestRunAction),
      test_devices=ConvertList(obj.test_devices, TestDeviceInfo),
      test_package_info=Convert(obj.test_package_info, TestPackageInfo),
      log_entries=ConvertList(event_log.GetEntries(obj), EventLogEntry),
  )


def _GetTestRunStateInfo(test_run: ndb_models.TestRun):
  """Determine an ndb_models.TestRun's relevant state information."""
  error_info = test_run.GetErrorInfo()
  if error_info:
    return error_info
  if test_run.state == ndb_models.TestRunState.PENDING:
    # TODO: consider adding a download progress endpoint instead
    for resource in test_run.test_resources:
      if resource.cache_url:
        continue  # already downloaded
      tracker = ndb_models.TestResourceTracker.get_by_id(resource.url)
      if tracker is None or tracker.completed:
        continue  # download either not started or already completed
      return 'Downloading %s [%d%%]' % (resource.name,
                                        100 * tracker.download_progress)
  return None


class TestRunSummary(messages.Message):
  """A test run."""
  id = messages.StringField(1)
  prev_test_run_id = messages.StringField(2)
  labels = messages.StringField(3, repeated=True)
  test_name = messages.StringField(4)
  device_specs = messages.StringField(5, repeated=True)
  state = messages.EnumField(ndb_models.TestRunState, 6)
  test_package_info = messages.MessageField(TestPackageInfo, 7)
  test_devices = messages.MessageField(TestDeviceInfo, 8, repeated=True)
  total_test_count = messages.IntegerField(9)
  failed_test_count = messages.IntegerField(10)
  failed_test_run_count = messages.IntegerField(11)
  create_time = message_types.DateTimeField(12)
  update_time = message_types.DateTimeField(13)


@Converter(ndb_models.TestRunSummary, TestRunSummary)
def _TestRunSummaryConverter(obj):
  """Converts a ndb_models.TestRunSummary object to a message."""
  return TestRunSummary(
      id=str(obj.key.id()),
      prev_test_run_id=(str(obj.prev_test_run_key.id())
                        if obj.prev_test_run_key else None),
      labels=obj.labels,
      test_name=obj.test_name,
      device_specs=obj.device_specs or ConvertToDeviceSpecs(obj.run_target),
      state=obj.state,
      test_package_info=Convert(obj.test_package_info, TestPackageInfo),
      test_devices=ConvertList(obj.test_devices, TestDeviceInfo),
      total_test_count=obj.total_test_count,
      failed_test_count=obj.failed_test_count,
      failed_test_run_count=obj.failed_test_run_count,
      create_time=_AddTimezone(obj.create_time),
      update_time=_AddTimezone(obj.update_time))


class TestRunSummaryList(messages.Message):
  """A list of test run summaries."""
  test_runs = messages.MessageField(TestRunSummary, 1, repeated=True)
  prev_page_token = messages.StringField(2)
  next_page_token = messages.StringField(3)


class TestRunMetadata(messages.Message):
  """Combination of a test run and its command attempts."""
  test_run = messages.MessageField(TestRun, 1, required=True)
  command_attempts = messages.MessageField(
      api_messages.CommandAttemptMessage, 2, repeated=True)


class TestRunMetadataList(messages.Message):
  """List of test run metadata.

  Attributes:
    test_runs: a list of test run metadata.
    server_version: a server version.
  """
  test_runs = messages.MessageField(TestRunMetadata, 1, repeated=True)
  server_version = messages.StringField(2)


class RerunContext(messages.Message):
  """Previous test run context used for rerun.

  Represents either a local test run (ID provided) or a remote test run (context
  file already uploaded to local file storage and filename provided).
  """
  test_run_id = messages.StringField(1)
  context_filename = messages.StringField(2)
  context_file_url = messages.StringField(3)


class NewTestRunRequest(messages.Message):
  """A request object for test_runs.new API."""
  labels = messages.StringField(1, repeated=True)
  test_run_config = messages.MessageField(TestRunConfig, 2)
  rerun_context = messages.MessageField(RerunContext, 3)
  rerun_configs = messages.MessageField(TestRunConfig, 4, repeated=True)
  required_report_id = messages.StringField(5)


class NodeConfig(messages.Message):
  """Node config."""
  env_vars = messages.MessageField(NameValuePair, 1, repeated=True)
  test_resource_default_download_urls = messages.MessageField(
      NameValuePair, 2, repeated=True)


@Converter(ndb_models.NodeConfig, NodeConfig)
def _NodeConfigConverter(obj):
  return NodeConfig(
      env_vars=ConvertNameValuePairs(obj.env_vars, NameValuePair),
      test_resource_default_download_urls=ConvertNameValuePairs(
          obj.test_resource_default_download_urls, NameValuePair))


@Converter(NodeConfig, ndb_models.NodeConfig)
def _NodeConfigMessageConverter(msg):
  """Converts a NodeConfig message into an object."""
  return ndb_models.NodeConfig(
      id=ndb_models.NODE_CONFIG_ID,
      env_vars=ConvertNameValuePairs(msg.env_vars, ndb_models.NameValuePair),
      test_resource_default_download_urls=ConvertNameValuePairs(
          msg.test_resource_default_download_urls, ndb_models.NameValuePair))


class PrivateNodeConfig(messages.Message):
  """User-specific settings."""
  ndb_version = messages.IntegerField(1)
  metrics_enabled = messages.BooleanField(2)
  gms_client_id = messages.StringField(3)
  setup_wizard_completed = messages.BooleanField(4)
  default_credentials = messages.MessageField(CredentialsInfo, 5)


@Converter(ndb_models.PrivateNodeConfig, PrivateNodeConfig)
def _PrivateNodeConfigConverter(obj):
  return PrivateNodeConfig(
      ndb_version=obj.ndb_version,
      metrics_enabled=obj.metrics_enabled,
      gms_client_id=obj.gms_client_id,
      setup_wizard_completed=obj.setup_wizard_completed,
      default_credentials=Convert(obj.default_credentials, CredentialsInfo))


@Converter(PrivateNodeConfig, ndb_models.PrivateNodeConfig)
def _PrivateNodeConfigMessageConverter(msg):
  """Converts a PrivateNodeConfig message into an object."""
  private_node_config = ndb_models.GetPrivateNodeConfig()
  private_node_config.ndb_version = msg.ndb_version
  private_node_config.metrics_enabled = msg.metrics_enabled
  private_node_config.gms_client_id = msg.gms_client_id
  private_node_config.setup_wizard_completed = msg.setup_wizard_completed
  return private_node_config


class FileCleanerOperation(messages.Message):
  """File cleaner operation."""
  type = messages.EnumField(
      ndb_models.FileCleanerOperationType, 1, required=True)
  params = messages.MessageField(NameValuePair, 2, repeated=True)


@Converter(ndb_models.FileCleanerOperation, FileCleanerOperation)
def _FileCleanerOperationConverter(obj):
  return FileCleanerOperation(
      type=obj.type, params=ConvertNameValuePairs(obj.params, NameValuePair))


@Converter(FileCleanerOperation, ndb_models.FileCleanerOperation)
def _FileCleanerOperationMessageConverter(msg):
  """Converts a FileCleanerOperation message into an object."""
  return ndb_models.FileCleanerOperation(
      type=msg.type,
      params=ConvertNameValuePairs(msg.params, ndb_models.NameValuePair))


class FileCleanerCriterion(messages.Message):
  """File cleaner criterion."""
  type = messages.EnumField(
      ndb_models.FileCleanerCriterionType, 1, required=True)
  params = messages.MessageField(NameValuePair, 2, repeated=True)


@Converter(ndb_models.FileCleanerCriterion, FileCleanerCriterion)
def _FileCleanerCriterionConverter(obj):
  return FileCleanerCriterion(
      type=obj.type, params=ConvertNameValuePairs(obj.params, NameValuePair))


@Converter(FileCleanerCriterion, ndb_models.FileCleanerCriterion)
def _FileCleanerCriterionMessageConverter(msg):
  """Converts a FileCleanerCriterion message into an object."""
  return ndb_models.FileCleanerCriterion(
      type=msg.type,
      params=ConvertNameValuePairs(msg.params, ndb_models.NameValuePair))


class FileCleanerPolicy(messages.Message):
  """File cleaner policy."""
  name = messages.StringField(1, required=True)
  target = messages.EnumField(ndb_models.FileCleanerTargetType, 2)
  operation = messages.MessageField(FileCleanerOperation, 3, required=True)
  criteria = messages.MessageField(FileCleanerCriterion, 4, repeated=True)


@Converter(ndb_models.FileCleanerPolicy, FileCleanerPolicy)
def _FileCleanerPolicyConverter(obj):
  return FileCleanerPolicy(
      name=obj.name,
      target=obj.target,
      operation=Convert(obj.operation, FileCleanerOperation),
      criteria=ConvertList(obj.criteria, FileCleanerCriterion))


@Converter(FileCleanerPolicy, ndb_models.FileCleanerPolicy)
def _FileCleanerPolicyMessageConverter(msg):
  """Converts a FileCleanerPolicy message into an object."""
  return ndb_models.FileCleanerPolicy(
      name=msg.name,
      target=msg.target,
      operation=Convert(msg.operation, ndb_models.FileCleanerOperation),
      criteria=ConvertList(msg.criteria, ndb_models.FileCleanerCriterion))


class FileCleanerConfig(messages.Message):
  """File cleaner config."""
  name = messages.StringField(1, required=True)
  description = messages.StringField(2)
  directories = messages.StringField(3, repeated=True)
  policy_names = messages.StringField(4, repeated=True)


@Converter(ndb_models.FileCleanerConfig, FileCleanerConfig)
def _FileCleanerConfigConverter(obj):
  return FileCleanerConfig(
      name=obj.name,
      description=obj.description,
      directories=obj.directories,
      policy_names=obj.policy_names)


@Converter(FileCleanerConfig, ndb_models.FileCleanerConfig)
def _FileCleanerConfigMessageConverter(msg):
  """Converts a FileCleanerConfig message into an object."""
  return ndb_models.FileCleanerConfig(
      name=msg.name,
      description=msg.description,
      directories=msg.directories,
      policy_names=msg.policy_names)


class FileCleanerSettings(messages.Message):
  """File cleaner settings, which combine cleanup policies and configs."""
  policies = messages.MessageField(FileCleanerPolicy, 1, repeated=True)
  configs = messages.MessageField(FileCleanerConfig, 2, repeated=True)


@Converter(ndb_models.FileCleanerSettings, FileCleanerSettings)
def _FileCleanerSettingsConverter(obj):
  return FileCleanerSettings(
      policies=ConvertList(obj.policies, FileCleanerPolicy),
      configs=ConvertList(obj.configs, FileCleanerConfig))


@Converter(FileCleanerSettings, ndb_models.FileCleanerSettings)
def _FileCleanerSettingsMessageConverter(msg):
  """Converts a FileCleanerSettings message into an object."""
  return ndb_models.FileCleanerSettings(
      id=ndb_models.FILE_CLEANER_SETTINGS_ID,
      policies=ConvertList(msg.policies, ndb_models.FileCleanerPolicy),
      configs=ConvertList(msg.configs, ndb_models.FileCleanerConfig))


class NetdataAlarmStatus(messages.Enum):
  REMOVED = 0
  UNINITIALIZED = 1
  UNDEFINED = 2
  CLEAR = 3
  WARNING = 4
  CRITICAL = 5


class NetdataAlarm(messages.Message):
  hostname = messages.StringField(1, required=True)
  id = messages.IntegerField(2, required=True)
  name = messages.StringField(3, required=True)
  value = messages.StringField(4, required=True)
  status = messages.EnumField(NetdataAlarmStatus, 5, required=True)


class NetdataAlarmList(messages.Message):
  alarms = messages.MessageField(NetdataAlarm, 1, repeated=True)


class RequiredReport(messages.Message):
  """A required report."""

  id = messages.StringField(1, required=True)
  type = messages.EnumField(ndb_models.ReportType, 2)
  test_plans = messages.StringField(3, repeated=True)
  available = messages.BooleanField(4)
  test_run_id = messages.StringField(5)
  test_run_state = messages.EnumField(ndb_models.TestRunState, 6)


@Converter(ndb_models.RequiredReport, RequiredReport)
def _RequiredReportConverter(obj):
  test_run = obj.test_run_key.get() if obj.test_run_key else None
  return RequiredReport(
      id=str(obj.key.id()),
      type=obj.type,
      test_plans=obj.test_plans,
      available=obj.available,
      test_run_id=str(obj.test_run_key.id()) if obj.test_run_key else None,
      test_run_state=test_run.state if test_run else None,
  )


class Build(messages.Message):
  """A build."""
  id = messages.StringField(1)
  name = messages.StringField(2)
  fingerprint = messages.StringField(3)
  file_url = messages.StringField(4)
  size = messages.IntegerField(5)
  labels = messages.StringField(6, repeated=True)
  create_time = message_types.DateTimeField(7)
  update_time = message_types.DateTimeField(8)
  detection_status = messages.EnumField(
      ndb_models.XtsRequirementsDetectionStatus, 9
  )
  detection_start_time = message_types.DateTimeField(10)
  detection_error_reason = messages.StringField(11)
  detection_test_run_id = messages.StringField(12)
  required_reports = messages.MessageField(RequiredReport, 13, repeated=True)


@Converter(ndb_models.Build, Build)
def _BuildConverter(obj):
  required_reports = list(
      ndb_models.RequiredReport.query(
          ndb_models.RequiredReport.build_key == obj.key
      )
  )
  return Build(
      id=str(obj.key.id()) if obj.key else None,
      name=obj.name,
      fingerprint=obj.fingerprint,
      file_url=obj.file_url,
      size=obj.size,
      labels=obj.labels,
      create_time=_AddTimezone(obj.create_time),
      update_time=_AddTimezone(obj.update_time),
      detection_status=obj.detection_status,
      detection_start_time=_AddTimezone(obj.detection_start_time),
      detection_error_reason=obj.detection_error_reason,
      detection_test_run_id=str(obj.detection_test_run_key.id())
      if obj.detection_test_run_key
      else None,
      required_reports=ConvertList(required_reports, RequiredReport),
  )


class BuildList(messages.Message):
  """A list of builds."""

  builds = messages.MessageField(Build, 1, repeated=True)


class XtsRequirementsDetectionRequest(messages.Message):
  """Request to run xTS requirements detection."""

  device_spec = messages.StringField(1)
  test_resource_objs = messages.MessageField(TestResourceObj, 2, repeated=True)
