// Copyright 2016 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 "modules/sensor/Sensor.h"

#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "device/generic_sensor/public/interfaces/sensor.mojom-blink.h"
#include "modules/sensor/SensorErrorEvent.h"
#include "modules/sensor/SensorPollingStrategy.h"
#include "modules/sensor/SensorProviderProxy.h"
#include "modules/sensor/SensorReading.h"
#include "modules/sensor/SensorReadingEvent.h"

using namespace device::mojom::blink;

namespace blink {

Sensor::Sensor(ExecutionContext* executionContext, const SensorOptions& sensorOptions, SensorType type)
    : ActiveScriptWrappable(this)
    , ContextLifecycleObserver(executionContext)
    , PageVisibilityObserver(toDocument(executionContext)->page())
    , m_sensorOptions(sensorOptions)
    , m_type(type)
    , m_state(Sensor::SensorState::IDLE)
    , m_storedData()
{
}

Sensor::~Sensor() = default;

void Sensor::start(ScriptState* scriptState, ExceptionState& exceptionState)
{
    if (m_state != Sensor::SensorState::IDLE && m_state != Sensor::SensorState::ERRORED) {
        exceptionState.throwDOMException(InvalidStateError, "Cannot start because SensorState is not idle or errored");
        return;
    }

    initSensorProxyIfNeeded();

    if (!m_sensorProxy) {
        exceptionState.throwDOMException(InvalidStateError, "The Sensor is no longer associated to a frame.");
        return;
    }

    startListening();
}

void Sensor::stop(ScriptState*, ExceptionState& exceptionState)
{
    if (m_state == Sensor::SensorState::IDLE || m_state == Sensor::SensorState::ERRORED) {
        exceptionState.throwDOMException(InvalidStateError, "Cannot stop because SensorState is either idle or errored");
        return;
    }

    stopListening();
}

static String ToString(Sensor::SensorState state)
{
    switch (state) {
    case Sensor::SensorState::IDLE:
        return "idle";
    case Sensor::SensorState::ACTIVATING:
        return "activating";
    case Sensor::SensorState::ACTIVE:
        return "active";
    case Sensor::SensorState::ERRORED:
        return "errored";
    default:
        NOTREACHED();
    }
    return "idle";
}

// Getters
String Sensor::state() const
{
    return ToString(m_state);
}

SensorReading* Sensor::reading() const
{
    return m_sensorReading.get();
}

DEFINE_TRACE(Sensor)
{
    visitor->trace(m_sensorProxy);
    visitor->trace(m_sensorReading);
    ActiveScriptWrappable::trace(visitor);
    ContextLifecycleObserver::trace(visitor);
    PageVisibilityObserver::trace(visitor);
    EventTargetWithInlineData::trace(visitor);
}

bool Sensor::hasPendingActivity() const
{
    if (m_state == Sensor::SensorState::IDLE || m_state == Sensor::SensorState::ERRORED)
        return false;
    return hasEventListeners();
}

void Sensor::initSensorProxyIfNeeded()
{
    if (m_sensorProxy)
        return;

    Document* document = toDocument(getExecutionContext());
    if (!document || !document->frame())
        return;

    m_sensorProxy = SensorProviderProxy::from(document->frame())->getOrCreateSensor(m_type);
}

void Sensor::contextDestroyed()
{
    if (m_state == Sensor::SensorState::ACTIVE || m_state == Sensor::SensorState::ACTIVATING)
        stopListening();
}

void Sensor::onSensorInitialized()
{
    if (m_state != Sensor::SensorState::ACTIVATING)
        return;

    startListening();
}

void Sensor::onSensorReadingChanged()
{
    if (m_polling)
        m_polling->onSensorReadingChanged();
}

void Sensor::onSensorError()
{
    reportError();
}

void Sensor::onStartRequestCompleted(bool result)
{
    if (m_state != Sensor::SensorState::ACTIVATING)
        return;

    if (!result) {
        reportError();
        return;
    }

    DCHECK(m_configuration);
    DCHECK(m_sensorProxy);
    auto pollCallback = WTF::bind(&Sensor::pollForData, wrapWeakPersistent(this));
    DCHECK_GT(m_configuration->frequency, 0);
    m_polling = SensorPollingStrategy::create(1 / m_configuration->frequency, std::move(pollCallback), m_sensorProxy->reportingMode());
    updateState(Sensor::SensorState::ACTIVE);
}

void Sensor::onStopRequestCompleted(bool result)
{
    if (m_state == Sensor::SensorState::IDLE)
        return;

    if (!result)
        reportError();

    DCHECK(m_sensorProxy);
    m_sensorProxy->removeObserver(this);
}

void Sensor::pageVisibilityChanged()
{
    updatePollingStatus();

    if (!m_sensorProxy || !m_sensorProxy->isInitialized())
        return;

    if (page()->visibilityState() != PageVisibilityStateVisible) {
        m_sensorProxy->suspend();
    } else {
        m_sensorProxy->resume();
    }
}

void Sensor::startListening()
{
    DCHECK(m_sensorProxy);
    updateState(Sensor::SensorState::ACTIVATING);
    if (!m_sensorReading) {
        m_sensorReading = createSensorReading(m_sensorProxy);
        DCHECK(m_sensorReading);
    }

    m_sensorProxy->addObserver(this);
    if (!m_sensorProxy->isInitialized()) {
        m_sensorProxy->initialize();
        return;
    }

    if (!m_configuration) {
        m_configuration = createSensorConfig(m_sensorOptions, *m_sensorProxy->defaultConfig());
        DCHECK(m_configuration);
    }

    auto startCallback = WTF::bind(&Sensor::onStartRequestCompleted, wrapWeakPersistent(this));
    m_sensorProxy->addConfiguration(m_configuration->Clone(), std::move(startCallback));
}

void Sensor::stopListening()
{
    DCHECK(m_sensorProxy);
    m_sensorReading = nullptr;
    updateState(Sensor::SensorState::IDLE);

    if (m_sensorProxy->isInitialized()) {
        auto callback = WTF::bind(&Sensor::onStopRequestCompleted, wrapWeakPersistent(this));
        DCHECK(m_configuration);
        m_sensorProxy->removeConfiguration(m_configuration->Clone(), std::move(callback));
    } else {
        m_sensorProxy->removeObserver(this);
    }
}

void Sensor::pollForData()
{
    if (m_state != Sensor::SensorState::ACTIVE) {
        DCHECK(m_polling);
        m_polling->stopPolling();
        return;
    }

    DCHECK(m_sensorProxy);
    DCHECK(m_sensorProxy->isInitialized());
    m_sensorProxy->updateInternalReading();

    DCHECK(m_sensorReading);
    if (m_sensorReading->isReadingUpdated(m_storedData))
        dispatchEvent(SensorReadingEvent::create(EventTypeNames::change, m_sensorReading));

    m_storedData = m_sensorProxy->reading();
}

void Sensor::updateState(Sensor::SensorState newState)
{
    if (newState == m_state)
        return;
    m_state = newState;
    dispatchEvent(Event::create(EventTypeNames::statechange));
    updatePollingStatus();
}

void Sensor::reportError()
{
    updateState(Sensor::SensorState::ERRORED);
    // TODO(Mikhail) : Dispatch Sensor Error event.
}

void Sensor::updatePollingStatus()
{
    if (!m_polling)
        return;

    if (m_state != Sensor::SensorState::ACTIVE
        || page()->visibilityState() != PageVisibilityStateVisible) {
        m_polling->stopPolling();
    } else {
        m_polling->startPolling();
    }
}

} // namespace blink
