// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "diagnostics/wilco_dtc_supportd/telemetry/ec_service_test_utils.h"

#include <base/logging.h>

namespace diagnostics {

namespace {

using EcEvent = diagnostics::EcService::EcEvent;

// A meaningless and meaningful EcEvent::Type
const auto kNonSystemNotifyType = static_cast<EcEvent::Type>(0xabcd);
const auto kSystemNotifyType = static_cast<EcEvent::Type>(0x0012);

// Valid payloads of |EcEvent::Type::SYSTEM_NOTIFY| type
const uint16_t kEcEventPayloadNonWilcoCharger[] = {0x0000, 0x0000, 0x0001,
                                                   0x0000, 0x0000, 0x0000};
const uint16_t kEcEventPayloadLowPowerCharger[] = {0x0000, 0x0000, 0x0002,
                                                   0x0000, 0x0000, 0x0000};
const uint16_t kEcEventPayloadBatteryAuth[] = {0x0003, 0x0000, 0x0001,
                                               0x0000, 0x0000, 0x0000};
const uint16_t kEcEventPayloadDockDisplay[] = {0x0008, 0x0200, 0x0000, 0x0000};
const uint16_t kEcEventPayloadDockThunderbolt[] = {0x0008, 0x0000, 0x0000,
                                                   0x0100};
const uint16_t kEcEventPayloadIncompatibleDock[] = {0x0008, 0x0000, 0x0000,
                                                    0x1000};
const uint16_t kEcEventPayloadDockError[] = {0x0008, 0x0000, 0x0000, 0x8000};

// Malformed payloads of |EcEvent::Type::SYSTEM_NOTIFY| type
const uint16_t kEcEventPayloadAcAdapterNoFlags[] = {0x0000, 0x0000, 0x0000,
                                                    0x0000, 0x0000, 0x0000};
const uint16_t kEcEventPayloadChargerNoFlags[] = {0x0003, 0x0000, 0x0000,
                                                  0x0000, 0x0000, 0x0000};
const uint16_t kEcEventPayloadUsbCNoFlags[] = {0x0008, 0x0000, 0x0000, 0x0000};
const uint16_t kEcEventPayloadNonWilcoChargerBadSubType[] = {
    0xffff, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000};

}  // namespace

// Valid EcEvents
const EcEvent kEcEventNonWilcoCharger =
    EcEvent(6, kSystemNotifyType, kEcEventPayloadNonWilcoCharger);
const EcEvent kEcEventLowPowerCharger =
    EcEvent(6, kSystemNotifyType, kEcEventPayloadLowPowerCharger);
const EcEvent kEcEventBatteryAuth =
    EcEvent(6, kSystemNotifyType, kEcEventPayloadBatteryAuth);
const EcEvent kEcEventDockDisplay =
    EcEvent(4, kSystemNotifyType, kEcEventPayloadDockDisplay);
const EcEvent kEcEventDockThunderbolt =
    EcEvent(4, kSystemNotifyType, kEcEventPayloadDockThunderbolt);
const EcEvent kEcEventIncompatibleDock =
    EcEvent(4, kSystemNotifyType, kEcEventPayloadIncompatibleDock);
const EcEvent kEcEventDockError =
    EcEvent(4, kSystemNotifyType, kEcEventPayloadDockError);

// Non |EcEvent::Type::SYSTEM_NOTIFY| type
const EcEvent kEcEventNonSysNotification =
    EcEvent(6, kNonSystemNotifyType, kEcEventPayloadNonWilcoCharger);

// Invalid EcEvents
const EcEvent kEcEventAcAdapterNoFlags =
    EcEvent(6, kSystemNotifyType, kEcEventPayloadAcAdapterNoFlags);
const EcEvent kEcEventChargerNoFlags =
    EcEvent(6, kSystemNotifyType, kEcEventPayloadChargerNoFlags);
const EcEvent kEcEventUsbCNoFlags =
    EcEvent(4, kSystemNotifyType, kEcEventPayloadUsbCNoFlags);
const EcEvent kEcEventNonWilcoChargerBadSubType =
    EcEvent(6, kSystemNotifyType, kEcEventPayloadNonWilcoChargerBadSubType);
const EcEvent kEcEventInvalidPayloadSize =
    EcEvent(8, kNonSystemNotifyType, kEcEventPayloadBatteryAuth);

std::string ConvertDataInWordsToString(const uint16_t* data, uint16_t size) {
  DCHECK_LE(static_cast<int>(size), 6);

  char data_in_bytes[12];
  for (uint16_t i = 0; i < size; i++) {
    data_in_bytes[i * 2] = data[i] & 255;
    data_in_bytes[i * 2 + 1] = data[i] >> 8;
  }
  return std::string(data_in_bytes, size * 2);
}

EcEvent GetEcEventWithReason(EcEvent::Reason reason) {
  switch (reason) {
    case EcEvent::Reason::kNonWilcoCharger:
      return kEcEventNonWilcoCharger;
    case EcEvent::Reason::kLowPowerCharger:
      return kEcEventLowPowerCharger;
    case EcEvent::Reason::kBatteryAuth:
      return kEcEventBatteryAuth;
    case EcEvent::Reason::kDockDisplay:
      return kEcEventDockDisplay;
    case EcEvent::Reason::kDockThunderbolt:
      return kEcEventDockThunderbolt;
    case EcEvent::Reason::kIncompatibleDock:
      return kEcEventIncompatibleDock;
    case EcEvent::Reason::kDockError:
      return kEcEventDockError;
    case EcEvent::Reason::kSysNotification:
      return kEcEventAcAdapterNoFlags;
    case EcEvent::Reason::kNonSysNotification:
      return kEcEventNonSysNotification;
  }
  NOTREACHED() << "Invalid EcEvent::Reason: " << static_cast<int>(reason);
}

}  // namespace diagnostics
