// 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(
      base::TimeTicks 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 Performance::MonotonicTimeToDOMHighResTimeStamp(
        time_origin, time_ticks);
  }

}  // namespace

PerformanceLifecycleTiming::PerformanceLifecycleTiming(
    const std::string& name, base::TimeTicks 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