// Copyright 2015 The Chromium 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 "device/bluetooth/bluetooth_discovery_filter.h"

#include <algorithm>

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "device/bluetooth/bluetooth_common.h"

namespace device {

BluetoothDiscoveryFilter::BluetoothDiscoveryFilter(
    BluetoothTransport transport) {
  SetTransport(transport);
}

BluetoothDiscoveryFilter::~BluetoothDiscoveryFilter() = default;

bool BluetoothDiscoveryFilter::GetRSSI(int16_t* out_rssi) const {
  DCHECK(out_rssi);
  if (!rssi_)
    return false;

  *out_rssi = *rssi_;
  return true;
}

void BluetoothDiscoveryFilter::SetRSSI(int16_t rssi) {
  rssi_ = rssi;
}

bool BluetoothDiscoveryFilter::GetPathloss(uint16_t* out_pathloss) const {
  DCHECK(out_pathloss);
  if (!pathloss_)
    return false;

  *out_pathloss = *pathloss_;
  return true;
}

void BluetoothDiscoveryFilter::SetPathloss(uint16_t pathloss) {
  pathloss_ = pathloss;
}

BluetoothTransport BluetoothDiscoveryFilter::GetTransport() const {
  return transport_;
}

void BluetoothDiscoveryFilter::SetTransport(BluetoothTransport transport) {
  DCHECK(transport != BLUETOOTH_TRANSPORT_INVALID);
  transport_ = transport;
}

void BluetoothDiscoveryFilter::GetUUIDs(
    std::set<device::BluetoothUUID>& out_uuids) const {
  out_uuids.clear();

  for (const auto& uuid : uuids_)
    out_uuids.insert(*uuid);
}

void BluetoothDiscoveryFilter::AddUUID(const device::BluetoothUUID& uuid) {
  DCHECK(uuid.IsValid());
  for (const auto& uuid_it : uuids_) {
    if (*uuid_it == uuid)
      return;
  }

  uuids_.push_back(std::make_unique<device::BluetoothUUID>(uuid));
}

void BluetoothDiscoveryFilter::CopyFrom(
    const BluetoothDiscoveryFilter& filter) {
  transport_ = filter.transport_;

  if (filter.uuids_.size()) {
    for (const auto& uuid : filter.uuids_)
      AddUUID(*uuid);
  } else
    uuids_.clear();

  rssi_ = filter.rssi_;
  pathloss_ = filter.pathloss_;
}

std::unique_ptr<device::BluetoothDiscoveryFilter>
BluetoothDiscoveryFilter::Merge(
    const device::BluetoothDiscoveryFilter* filter_a,
    const device::BluetoothDiscoveryFilter* filter_b) {
  std::unique_ptr<BluetoothDiscoveryFilter> result;

  if (!filter_a && !filter_b) {
    return result;
  }

  result.reset(new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_DUAL));

  if (!filter_a || !filter_b || filter_a->IsDefault() ||
      filter_b->IsDefault()) {
    return result;
  }

  // both filters are not empty, so they must have transport set.
  result->SetTransport(static_cast<BluetoothTransport>(filter_a->transport_ |
                                                       filter_b->transport_));

  // if both filters have uuids, them merge them. Otherwise uuids filter should
  // be left empty
  if (filter_a->uuids_.size() && filter_b->uuids_.size()) {
    std::set<device::BluetoothUUID> uuids;
    filter_a->GetUUIDs(uuids);
    for (auto& uuid : uuids)
      result->AddUUID(uuid);

    filter_b->GetUUIDs(uuids);
    for (auto& uuid : uuids)
      result->AddUUID(uuid);
  }

  if ((filter_a->rssi_ && filter_b->pathloss_) ||
      (filter_a->pathloss_ && filter_b->rssi_)) {
    // if both rssi and pathloss filtering is enabled in two different
    // filters, we can't tell which filter is more generic, and we don't set
    // proximity filtering on merged filter.
    return result;
  }

  if (filter_a->rssi_ && filter_b->rssi_) {
    result->SetRSSI(std::min(*filter_a->rssi_, *filter_b->rssi_));
  } else if (filter_a->pathloss_ && filter_b->pathloss_) {
    result->SetPathloss(std::max(*filter_a->pathloss_, *filter_b->pathloss_));
  }

  return result;
}

bool BluetoothDiscoveryFilter::Equals(
    const BluetoothDiscoveryFilter& other) const {
  if ((rssi_.has_value() != other.rssi_.has_value()) ||
      (rssi_ && other.rssi_ && *rssi_ != *other.rssi_)) {
    return false;
  }

  if ((pathloss_.has_value() != other.pathloss_.has_value()) ||
      (pathloss_ && other.pathloss_ && *pathloss_ != *other.pathloss_)) {
    return false;
  }

  if (transport_ != other.transport_)
    return false;

  std::set<device::BluetoothUUID> uuids_a, uuids_b;
  GetUUIDs(uuids_a);
  other.GetUUIDs(uuids_b);
  if (uuids_a != uuids_b)
    return false;

  return true;
}

bool BluetoothDiscoveryFilter::IsDefault() const {
  return !(rssi_ || pathloss_ || uuids_.size() ||
           transport_ != BLUETOOTH_TRANSPORT_DUAL);
}

}  // namespace device
