// Copyright 2021 The Cobalt Authors. All Rights Reserved.
//
// 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.


#include "cobalt/dom/performance_lifecycle_timing.h"
#include "cobalt/dom/performance.h"

namespace cobalt {
namespace dom {

namespace {

  std::string TranslateApplicationStateToString(
      base::ApplicationState state) {
    switch (state) {
      case base::kApplicationStateBlurred:
        return "ApplicationStateBlurred";
      case base::kApplicationStateConcealed:
        return "ApplicationStateConcealed";
      case base::kApplicationStateFrozen:
        return "ApplicationStateFrozen";
      case base::kApplicationStateStarted:
        return "ApplicationStateStarted";
      case base::kApplicationStateStopped:
        return "ApplicationStateStopped";
    }

    NOTREACHED() << "state = " << state;
    return "INVALID_APPLICATION_STATE";
  }

    DOMHighResTimeStamp ConvertSbTimeMonotonicToDOMHiResTimeStamp(
      const DOMHighResTimeStamp time_origin, SbTimeMonotonic monotonic_time) {
    SbTimeMonotonic time_delta = SbTimeGetNow() - SbTimeGetMonotonicNow();
    base::Time base_time = base::Time::FromSbTime(time_delta + monotonic_time);
    base::TimeTicks time_ticks =
        base::TimeTicks::FromInternalValue(static_cast<int64_t>(
            base_time.ToJsTime()));
    return ClampTimeStampMinimumResolution(time_ticks,
        Performance::kPerformanceTimerMinResolutionInMicroseconds) - time_origin;
  }

}  // namespace

PerformanceLifecycleTiming::PerformanceLifecycleTiming(
    const std::string& name, const DOMHighResTimeStamp time_origin)
    : PerformanceEntry(name, 0.0, 0.0), time_origin_(time_origin) {}

DOMHighResTimeStamp PerformanceLifecycleTiming::app_preload() const {
  return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_preload);
}

DOMHighResTimeStamp PerformanceLifecycleTiming::app_start() const {
  return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_start);
}

DOMHighResTimeStamp PerformanceLifecycleTiming::app_blur() const {
  return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_blur);
}

DOMHighResTimeStamp PerformanceLifecycleTiming::app_focus() const {
  return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_focus);
}

DOMHighResTimeStamp PerformanceLifecycleTiming::app_conceal() const {
  return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_conceal);
}

DOMHighResTimeStamp PerformanceLifecycleTiming::app_reveal() const {
  return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_reveal);
}

DOMHighResTimeStamp PerformanceLifecycleTiming::app_freeze() const {
  return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_freeze);
}

DOMHighResTimeStamp PerformanceLifecycleTiming::app_unfreeze() const {
  return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_unfreeze);
}

DOMHighResTimeStamp PerformanceLifecycleTiming::app_deeplink() const {
  return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_deeplink);
}

std::string PerformanceLifecycleTiming::current_state() const {
  return TranslateApplicationStateToString(
      lifecycle_timing_info_.current_state);
}

std::string PerformanceLifecycleTiming::last_state() const {
  return TranslateApplicationStateToString(
      lifecycle_timing_info_.last_state);
}

void PerformanceLifecycleTiming::SetApplicationState(
    base::ApplicationState state, SbTimeMonotonic timestamp) {
  switch (state) {
    case base::kApplicationStateBlurred:
      if (GetCurrentState() == base::kApplicationStateStarted ||
          // TODO: Figure out why the current state is not set
          // by SetApplicationStartOrPreloadTimestamp.
          GetCurrentState() == base::kApplicationStateStopped) {
        lifecycle_timing_info_.app_blur = timestamp;
      } else if (GetCurrentState() == base::kApplicationStateConcealed) {
        lifecycle_timing_info_.app_reveal = timestamp;
      } else {
        DLOG(INFO) << "Current State: " <<
            TranslateApplicationStateToString(GetCurrentState());
        DLOG(INFO) << "Next State: " <<
            TranslateApplicationStateToString(state);
        NOTREACHED() << "Invalid application state transition.";
      }
      break;
    case base::kApplicationStateConcealed:
      if (GetCurrentState() == base::kApplicationStateBlurred ||
          GetCurrentState() == base::kApplicationStateStopped) {
        lifecycle_timing_info_.app_conceal = timestamp;
      } else if (GetCurrentState() == base::kApplicationStateFrozen) {
        lifecycle_timing_info_.app_unfreeze = timestamp;
      } else {
        DLOG(INFO) << "Current State: " <<
            TranslateApplicationStateToString(GetCurrentState());
        DLOG(INFO) << "Next State: " <<
            TranslateApplicationStateToString(state);
        NOTREACHED() << "Invalid application state transition.";
      }
      break;
    case base::kApplicationStateFrozen:
      lifecycle_timing_info_.app_freeze = timestamp;
      break;
    case base::kApplicationStateStarted:
      if (GetCurrentState() == base::kApplicationStateBlurred) {
        if (lifecycle_timing_info_.app_preload != 0) {
          lifecycle_timing_info_.app_start = timestamp;
        }
        lifecycle_timing_info_.app_focus = timestamp;
      }
      break;
    case base::kApplicationStateStopped:
      NOTREACHED() << "Not support the application stopped state.";
      break;
    default:
      NOTREACHED() << "Invalid application state = " << state;
      break;
  }
  SetLifecycleTimingInfoState(state);
}

void PerformanceLifecycleTiming::SetApplicationStartOrPreloadTimestamp(
    bool is_preload, SbTimeMonotonic timestamp) {
  if (is_preload) {
    lifecycle_timing_info_.app_preload = timestamp;
    SetLifecycleTimingInfoState(base::kApplicationStateConcealed);
  } else {
    lifecycle_timing_info_.app_start = timestamp;
    SetLifecycleTimingInfoState(base::kApplicationStateStarted);
  }
}

void PerformanceLifecycleTiming::SetDeepLinkTimestamp(
    SbTimeMonotonic timestamp) {
  lifecycle_timing_info_.app_deeplink = timestamp;
}

base::ApplicationState PerformanceLifecycleTiming::GetCurrentState() const {
  return lifecycle_timing_info_.current_state;
}

void PerformanceLifecycleTiming::SetLifecycleTimingInfoState(
    base::ApplicationState state) {
  lifecycle_timing_info_.last_state =
      lifecycle_timing_info_.current_state;
  lifecycle_timing_info_.current_state = state;
}

DOMHighResTimeStamp PerformanceLifecycleTiming::ReportDOMHighResTimeStamp(
    SbTimeMonotonic timestamp) const {
  if (timestamp != 0) {
    return ConvertSbTimeMonotonicToDOMHiResTimeStamp(time_origin_,
                                                     timestamp);
  }
  return PerformanceEntry::start_time();
}

}  // namespace dom
}  // namespace cobalt