// Copyright 2014 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/geolocation/geolocation_service_impl.h"

#include <utility>

#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "device/geolocation/geolocation_service_context.h"

namespace device {

namespace {

// Geoposition error codes for reporting in UMA.
enum GeopositionErrorCode {
  // NOTE: Do not renumber these as that would confuse interpretation of
  // previously logged data. When making changes, also update the enum list
  // in tools/metrics/histograms/histograms.xml to keep it in sync.

  // There was no error.
  GEOPOSITION_ERROR_CODE_NONE = 0,

  // User denied use of geolocation.
  GEOPOSITION_ERROR_CODE_PERMISSION_DENIED = 1,

  // Geoposition could not be determined.
  GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE = 2,

  // Timeout.
  GEOPOSITION_ERROR_CODE_TIMEOUT = 3,

  // NOTE: Add entries only immediately above this line.
  GEOPOSITION_ERROR_CODE_COUNT = 4
};

void RecordGeopositionErrorCode(Geoposition::ErrorCode error_code) {
  GeopositionErrorCode code = GEOPOSITION_ERROR_CODE_NONE;
  switch (error_code) {
    case Geoposition::ERROR_CODE_NONE:
      code = GEOPOSITION_ERROR_CODE_NONE;
      break;
    case Geoposition::ERROR_CODE_PERMISSION_DENIED:
      code = GEOPOSITION_ERROR_CODE_PERMISSION_DENIED;
      break;
    case Geoposition::ERROR_CODE_POSITION_UNAVAILABLE:
      code = GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE;
      break;
    case Geoposition::ERROR_CODE_TIMEOUT:
      code = GEOPOSITION_ERROR_CODE_TIMEOUT;
      break;
  }
  UMA_HISTOGRAM_ENUMERATION("Geolocation.LocationUpdate.ErrorCode", code,
                            GEOPOSITION_ERROR_CODE_COUNT);
}

}  // namespace

GeolocationServiceImpl::GeolocationServiceImpl(
    mojo::InterfaceRequest<GeolocationService> request,
    GeolocationServiceContext* context,
    const base::Closure& update_callback)
    : binding_(this, std::move(request)),
      context_(context),
      update_callback_(update_callback),
      high_accuracy_(false),
      has_position_to_report_(false) {
  DCHECK(context_);
  binding_.set_connection_error_handler(base::Bind(
      &GeolocationServiceImpl::OnConnectionError, base::Unretained(this)));
}

GeolocationServiceImpl::~GeolocationServiceImpl() {
  // Make sure to respond to any pending callback even without a valid position.
  if (!position_callback_.is_null()) {
    if (!current_position_.valid) {
      current_position_.error_code = mojom::Geoposition::ErrorCode(
          GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE);
      current_position_.error_message.clear();
    }
    ReportCurrentPosition();
  }
}

void GeolocationServiceImpl::PauseUpdates() {
  geolocation_subscription_.reset();
}

void GeolocationServiceImpl::ResumeUpdates() {
  if (position_override_.Validate()) {
    OnLocationUpdate(position_override_);
    return;
  }

  StartListeningForUpdates();
}

void GeolocationServiceImpl::StartListeningForUpdates() {
  geolocation_subscription_ =
      GeolocationProvider::GetInstance()->AddLocationUpdateCallback(
          base::Bind(&GeolocationServiceImpl::OnLocationUpdate,
                     base::Unretained(this)),
          high_accuracy_);
}

void GeolocationServiceImpl::SetHighAccuracy(bool high_accuracy) {
  UMA_HISTOGRAM_BOOLEAN(
      "Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy",
      high_accuracy);
  high_accuracy_ = high_accuracy;

  if (position_override_.Validate()) {
    OnLocationUpdate(position_override_);
    return;
  }

  StartListeningForUpdates();
}

void GeolocationServiceImpl::QueryNextPosition(
    const QueryNextPositionCallback& callback) {
  if (!position_callback_.is_null()) {
    DVLOG(1) << "Overlapped call to QueryNextPosition!";
    OnConnectionError();  // Simulate a connection error.
    return;
  }

  position_callback_ = callback;

  if (has_position_to_report_)
    ReportCurrentPosition();
}

void GeolocationServiceImpl::SetOverride(const Geoposition& position) {
  position_override_ = position;
  if (!position_override_.Validate()) {
    ResumeUpdates();
  }

  geolocation_subscription_.reset();

  OnLocationUpdate(position_override_);
}

void GeolocationServiceImpl::ClearOverride() {
  position_override_ = Geoposition();
  StartListeningForUpdates();
}

void GeolocationServiceImpl::OnConnectionError() {
  context_->ServiceHadConnectionError(this);

  // The above call deleted this instance, so the only safe thing to do is
  // return.
}

void GeolocationServiceImpl::OnLocationUpdate(const Geoposition& position) {
  RecordGeopositionErrorCode(position.error_code);
  DCHECK(context_);

  update_callback_.Run();

  current_position_.valid = position.Validate();
  current_position_.latitude = position.latitude;
  current_position_.longitude = position.longitude;
  current_position_.altitude = position.altitude;
  current_position_.accuracy = position.accuracy;
  current_position_.altitude_accuracy = position.altitude_accuracy;
  current_position_.heading = position.heading;
  current_position_.speed = position.speed;
  current_position_.timestamp = position.timestamp.ToDoubleT();
  current_position_.error_code =
      mojom::Geoposition::ErrorCode(position.error_code);
  current_position_.error_message = position.error_message;

  has_position_to_report_ = true;

  if (!position_callback_.is_null())
    ReportCurrentPosition();
}

void GeolocationServiceImpl::ReportCurrentPosition() {
  position_callback_.Run(current_position_.Clone());
  position_callback_.Reset();
  has_position_to_report_ = false;
}

}  // namespace device
