// Copyright (C) 2023 The Android Open Source Project
//
// 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.

import m from 'mithril';

import {copyToClipboard} from '../../base/clipboard';
import {Icons} from '../../base/semantic_icons';
import {Duration, duration} from '../../base/time';
import {
  DurationPrecision,
  durationPrecision,
  setDurationPrecision,
  TimestampFormat,
  timestampFormat,
} from '../../core/timestamp_format';
import {raf} from '../../core/raf_scheduler';
import {Anchor} from '../../widgets/anchor';
import {MenuDivider, MenuItem, PopupMenu2} from '../../widgets/menu';

import {menuItemForFormat} from './timestamp';

interface DurationWidgetAttrs {
  dur: duration;
  extraMenuItems?: m.Child[];
}

export class DurationWidget implements m.ClassComponent<DurationWidgetAttrs> {
  view({attrs}: m.Vnode<DurationWidgetAttrs>) {
    const {dur} = attrs;
    return m(
      PopupMenu2,
      {
        trigger: m(Anchor, renderDuration(dur)),
      },
      m(MenuItem, {
        icon: Icons.Copy,
        label: `Copy raw value`,
        onclick: () => {
          copyToClipboard(dur.toString());
        },
      }),
      m(
        MenuItem,
        {
          label: 'Set time format',
        },
        menuItemForFormat(TimestampFormat.Timecode, 'Timecode'),
        menuItemForFormat(TimestampFormat.UTC, 'Realtime (UTC)'),
        menuItemForFormat(TimestampFormat.TraceTz, 'Realtime (Trace TZ)'),
        menuItemForFormat(TimestampFormat.Seconds, 'Seconds'),
        menuItemForFormat(TimestampFormat.Raw, 'Raw'),
        menuItemForFormat(
          TimestampFormat.RawLocale,
          'Raw (with locale-specific formatting)',
        ),
      ),
      m(
        MenuItem,
        {
          label: 'Duration precision',
          disabled: !durationPrecisionHasEffect(),
          title: 'Not configurable with current time format',
        },
        menuItemForPrecision(DurationPrecision.Full, 'Full'),
        menuItemForPrecision(DurationPrecision.HumanReadable, 'Human readable'),
      ),
      attrs.extraMenuItems ? [m(MenuDivider), attrs.extraMenuItems] : null,
    );
  }
}

function menuItemForPrecision(
  value: DurationPrecision,
  label: string,
): m.Children {
  return m(MenuItem, {
    label,
    active: value === durationPrecision(),
    onclick: () => {
      setDurationPrecision(value);
      raf.scheduleFullRedraw();
    },
  });
}

function durationPrecisionHasEffect(): boolean {
  switch (timestampFormat()) {
    case TimestampFormat.Timecode:
    case TimestampFormat.UTC:
    case TimestampFormat.TraceTz:
      return true;
    default:
      return false;
  }
}

export function renderDuration(dur: duration): string {
  const fmt = timestampFormat();
  switch (fmt) {
    case TimestampFormat.UTC:
    case TimestampFormat.TraceTz:
    case TimestampFormat.Timecode:
      return renderFormattedDuration(dur);
    case TimestampFormat.Raw:
      return dur.toString();
    case TimestampFormat.RawLocale:
      return dur.toLocaleString();
    case TimestampFormat.Seconds:
      return Duration.formatSeconds(dur);
    default:
      const x: never = fmt;
      throw new Error(`Invalid format ${x}`);
  }
}

function renderFormattedDuration(dur: duration): string {
  const fmt = durationPrecision();
  switch (fmt) {
    case DurationPrecision.HumanReadable:
      return Duration.humanise(dur);
    case DurationPrecision.Full:
      return Duration.format(dur);
    default:
      const x: never = fmt;
      throw new Error(`Invalid format ${x}`);
  }
}
