// Copyright (C) 2026 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 {GateDetector} from '../../../base/mithril_utils';
import type {
  LineChartData,
  LineChartSeries,
} from '../../../components/widgets/charts/line_chart';
import type {App} from '../../../public/app';
import {Button, ButtonGroup, ButtonVariant} from '../../../widgets/button';
import {Chip} from '../../../widgets/chip';
import {Intent} from '../../../widgets/common';
import {MenuDivider, MenuItem, PopupMenu} from '../../../widgets/menu';
import {PopupPosition} from '../../../widgets/popup';
import {RadioGroup} from '../../../widgets/radio_group';
import {Page} from '../components/page';
import type {
  LiveSession,
  ProfileView,
  SnapshotData,
} from '../sessions/live_session';
import './dashboard.scss';
import {ProfilePage} from './profile_page';
import {renderPageCacheTab} from './tabs/page_cache';
import {renderPressureSwapTab} from './tabs/pressure_swap';
import {ProcessesTab} from './tabs/processes';
import {renderSystemTab} from './tabs/system';

type Tab = 'processes' | 'system' | 'file_cache' | 'pressure_swap';

function buildProcessMemoryBreakdown(
  data: SnapshotData,
  pid: number,
  t0: number,
): LineChartData | undefined {
  // SnapshotData keys process counters by upid; resolve from pid.
  let upid: number | undefined;
  for (const info of data.processInfo.values()) {
    if (info.pid === pid) {
      upid = info.upid;
      break;
    }
  }
  if (upid === undefined) return undefined;
  const pidCounters = data.processCountersByUpid.get(upid);
  if (pidCounters === undefined) return undefined;
  const SERIES_NAMES = ['RSS Anon + Swap', 'File', 'DMA-BUF'] as const;
  const counterMapping: Record<string, string> = {
    'mem.rss.anon': 'RSS Anon + Swap',
    'mem.swap': 'RSS Anon + Swap',
    'mem.rss.file': 'File',
    'mem.dmabuf_rss': 'DMA-BUF',
  };
  const tsSet = new Set<number>();
  const bySeriesTs = new Map<number, Map<string, number>>();
  for (const [counterName, samples] of pidCounters) {
    const seriesName = counterMapping[counterName];
    if (seriesName === undefined) continue;
    for (const {ts, value} of samples) {
      tsSet.add(ts);
      let seriesMap = bySeriesTs.get(ts);
      if (seriesMap === undefined) {
        seriesMap = new Map();
        bySeriesTs.set(ts, seriesMap);
      }
      seriesMap.set(
        seriesName,
        (seriesMap.get(seriesName) ?? 0) + Math.round(value / 1024),
      );
    }
  }
  const timestamps = [...tsSet].sort((a, b) => a - b);
  if (timestamps.length < 2) return undefined;
  const colors: Record<string, string> = {
    'RSS Anon + Swap': 'var(--pf-color-warning)',
    'File': 'var(--pf-color-success)',
    'DMA-BUF': 'var(--pf-color-primary)',
  };
  const series: LineChartSeries[] = [];
  for (const name of SERIES_NAMES) {
    const points = timestamps.map((ts) => ({
      x: (ts - t0) / 1e9,
      y: bySeriesTs.get(ts)?.get(name) ?? 0,
    }));
    if (points.some((p) => p.y > 0)) {
      series.push({name, points, color: colors[name]});
    }
  }
  if (series.length === 0) return undefined;
  return {series};
}

interface DashboardAttrs {
  readonly app: App;
  readonly session: LiveSession;
  readonly onStopped: () => void;
}

export class Dashboard implements m.ClassComponent<DashboardAttrs> {
  private activeTab: Tab = 'processes';
  private profileBaseline?: {anonSwap: number; file: number; dmabuf: number};

  view({attrs}: m.CVnode<DashboardAttrs>) {
    const {session} = attrs;
    return m(
      GateDetector,
      {
        onVisibilityChanged: (visible) =>
          visible ? session.resume() : session.pause(),
      },
      m(
        Page,

        // Title bar with status and actions (always shown).
        this.renderTitleBar(attrs),

        // Profile page or dashboard content.
        session.profile !== undefined
          ? this.renderProfilePage(attrs, session.profile)
          : this.renderDashboard(attrs),
      ),
    );
  }

  private renderTitleBar(attrs: DashboardAttrs): m.Children {
    return m(
      '.pf-memscope-title-bar',
      // Left: title + session pill (device + snapshot counter + pause/play).
      m(
        '.pf-memscope-title-bar__left',
        m('h1', 'Memscope'),
        attrs.session.profile === undefined && this.renderTabStrip(),
      ),
      this.renderSessionPill(attrs),
    );
  }

  private renderTabStrip(): m.Children {
    return m(
      RadioGroup,
      {
        intent: Intent.Primary,
        selectedValue: this.activeTab,
        onValueChange: (value) => {
          this.activeTab = value as Tab;
        },
      },
      m(RadioGroup.Button, {value: 'processes', icon: 'apps'}, 'Processes'),
      m(RadioGroup.Button, {value: 'system', icon: 'monitoring'}, 'System'),
      m(
        RadioGroup.Button,
        {value: 'file_cache', icon: 'file_copy'},
        'Page Cache',
      ),

      // Right: action buttons.
      m(
        RadioGroup.Button,
        {value: 'pressure_swap', icon: 'speed'},
        'Pressure, Faults & Swap',
      ),
    );
  }

  private renderSessionPill(attrs: DashboardAttrs): m.Children {
    const {session} = attrs;
    return m(
      '.pf-memscope-session-pill',
      // Device identity sits to the left of the button group.
      m(
        '.pf-memscope-session-pill__device',
        m('.pf-memscope-status-bar__dot', {
          class: session.isPaused ? 'pf-memscope-status-bar__dot--paused' : '',
        }),
        m('span', session.deviceName),
        session.data?.isUserDebug &&
          m(Chip, {label: 'userdebug', intent: Intent.Warning}),
      ),
      m(
        ButtonGroup,
        // Pause / Resume.
        m(Button, {
          variant: ButtonVariant.Filled,
          label: session.isPaused ? 'Resume' : 'Pause',
          icon: session.isPaused ? 'play_arrow' : 'pause',
          onclick: () => {
            session.togglePause();
            m.redraw();
          },
        }),
        // Overflow menu for session actions.
        m(
          PopupMenu,
          {
            trigger: m(Button, {
              variant: ButtonVariant.Filled,
              icon: 'more_vert',
            }),
            position: PopupPosition.BottomEnd,
          },

          m(MenuItem, {
            label: 'Stop & Open Trace',
            icon: 'open_in_new',
            disabled: session.lastTraceBuffer === undefined,
            onclick: () => this.stopAndOpenTrace(attrs),
          }),
          m(MenuItem, {
            label: 'Disconnect',
            icon: 'usb_off',
            onclick: () => attrs.onStopped(),
          }),
          m(MenuDivider),
          m(
            MenuItem,
            {
              label: 'Snapshot stats',
              icon: 'photo_camera',
            },
            this.renderSnapshotStats(session),
          ),
        ),
      ),
    );
  }

  private renderDashboard(attrs: DashboardAttrs): m.Children {
    const {session} = attrs;
    return [
      this.activeTab === 'processes' && m(ProcessesTab, {session}),
      this.activeTab === 'system' && renderSystemTab(session),
      this.activeTab === 'file_cache' && renderPageCacheTab(session),
      this.activeTab === 'pressure_swap' && renderPressureSwapTab(session),
      !session.data && m('.pf-memscope-placeholder', 'Waiting for data\u2026'),
    ];
  }

  private renderSnapshotStats(session: LiveSession): m.Children {
    if (session.lastSnapshotMs <= 0) {
      return m(
        '.pf-memscope-snapshot-info',
        m('.pf-memscope-snapshot-info__empty', 'Waiting for snapshot…'),
      );
    }
    return m(
      '.pf-memscope-snapshot-info',
      m('.pf-memscope-snapshot-info__heading', 'Snapshot'),
      m(
        '.pf-memscope-snapshot-info__row',
        m('span', 'Count'),
        m('span', `#${session.snapshotCount}`),
      ),
      m(
        '.pf-memscope-snapshot-info__row',
        m('span', 'Size'),
        m('span', `${session.lastSnapshotSizeKb.toFixed(0)}kB`),
      ),
      session.lastBufferUsagePct !== undefined &&
        m(
          '.pf-memscope-snapshot-info__row',
          m('span', 'Buffer usage'),
          m('span', `${session.lastBufferUsagePct.toFixed(1)}%`),
        ),
      session.data !== undefined && [
        m('.pf-memscope-snapshot-info__heading', 'Counter range'),
        m(
          '.pf-memscope-snapshot-info__row',
          m('span', 'First sample'),
          m('span', `${session.data.xMin.toFixed(1)}s`),
        ),
        m(
          '.pf-memscope-snapshot-info__row',
          m('span', 'Last sample'),
          m('span', `${session.data.xMax.toFixed(1)}s`),
        ),
      ],
      m('.pf-memscope-snapshot-info__heading', 'Timings'),
      m(
        '.pf-memscope-snapshot-info__row',
        m('span', 'Clone'),
        m('span', `${session.lastCloneMs}ms`),
      ),
      m(
        '.pf-memscope-snapshot-info__row',
        m('span', 'Parse'),
        m('span', `${session.lastParseMs}ms`),
      ),
      m(
        '.pf-memscope-snapshot-info__row',
        m('span', 'Query'),
        m('span', `${session.lastQueryMs}ms`),
      ),
      m(
        '.pf-memscope-snapshot-info__row',
        m('span', 'Extract'),
        m('span', `${session.lastExtractMs}ms`),
      ),
      m(
        '.pf-memscope-snapshot-info__row.pf-memscope-snapshot-info__sum',
        m('span', 'Total'),
        m('span', `${session.lastSnapshotMs}ms`),
      ),
      session.snapshotOverrun &&
        m(
          '.pf-memscope-snapshot-info__overrun',
          m('span.material-icons', 'warning'),
          'Exceeds interval — increase snapshot rate',
        ),
    );
  }

  private renderProfilePage(
    attrs: DashboardAttrs,
    profile: ProfileView,
  ): m.Children {
    const {session} = attrs;
    const data = session.data;
    const t0 = data?.ts0 ?? 0;
    const chartData = data
      ? buildProcessMemoryBreakdown(data, profile.pid, t0)
      : undefined;

    // Capture baseline from first chart data.
    if (this.profileBaseline === undefined && chartData !== undefined) {
      const first = (name: string): number => {
        const s = chartData.series.find(
          (sr: LineChartSeries) => sr.name === name,
        );
        return s !== undefined && s.points.length > 0 ? s.points[0].y : 0;
      };
      this.profileBaseline = {
        anonSwap: first('RSS Anon + Swap'),
        file: first('File'),
        dmabuf: first('DMA-BUF'),
      };
    }

    return m(ProfilePage, {
      state: profile.state as 'recording' | 'stopping' | 'finished',
      bufferUsagePct: profile.bufferUsagePct,
      processName: profile.processName,
      pid: profile.pid,
      startMs: profile.startMs,
      chartData,
      baseline: this.profileBaseline,
      onStop: () => {
        session.stopAndOpenProfile().then(() => {
          this.profileBaseline = undefined;
          m.redraw();
        });
      },
      onStopAndDownload: () => {
        session.stopAndDownloadProfile().then(() => {
          this.profileBaseline = undefined;
          m.redraw();
        });
      },
      onCancel: () => {
        session.cancelProfile().then(() => {
          this.profileBaseline = undefined;
          m.redraw();
        });
      },
    });
  }

  private async stopAndOpenTrace(attrs: DashboardAttrs) {
    const buffer = attrs.session.lastTraceBuffer;
    if (buffer === undefined) return;
    const fileName = `live-memory-${Date.now()}.perfetto-trace`;
    await attrs.session.dispose();
    attrs.app.openTraceFromBuffer({buffer, title: fileName, fileName});
  }
}
