// Copyright (C) 2020 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 {QueryResponse, runQuery} from '../common/queries';
import {raf} from '../core/raf_scheduler';
import {EngineProxy} from '../trace_processor/engine';

import {globals} from './globals';
import {createPage} from './pages';


interface StatsSectionAttrs {
  title: string;
  subTitle: string;
  sqlConstraints: string;
  cssClass: string;
  queryId: string;
}

function getEngine(name: string): EngineProxy|undefined {
  const currentEngine = globals.getCurrentEngine();
  if (currentEngine === undefined) return undefined;
  const engineId = currentEngine.id;
  return globals.engines.get(engineId)?.getProxy(name);
}

// Generic class that generate a <section> + <table> from the stats table.
// The caller defines the query constraint, title and styling.
// Used for errors, data losses and debugging sections.
class StatsSection implements m.ClassComponent<StatsSectionAttrs> {
  private queryResponse?: QueryResponse;

  constructor({attrs}: m.CVnode<StatsSectionAttrs>) {
    const engine = getEngine('StatsSection');
    if (engine === undefined) {
      return;
    }
    const query = `select name, value, cast(ifnull(idx, '') as text) as idx,
              description, severity, source from stats
              where ${attrs.sqlConstraints || '1=1'}
              order by name, idx`;
    runQuery(query, engine).then((resp: QueryResponse) => {
      this.queryResponse = resp;
      raf.scheduleFullRedraw();
    });
  }

  view({attrs}: m.CVnode<StatsSectionAttrs>) {
    const resp = this.queryResponse;
    if (resp === undefined || resp.totalRowCount === 0) {
      return m('');
    }
    if (resp.error) throw new Error(resp.error);

    const tableRows = [];
    for (const row of resp.rows) {
      const help = [];
      // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
      if (row.description) {
        help.push(m('i.material-icons.contextual-help', 'help_outline'));
      }
      const idx = row.idx !== '' ? `[${row.idx}]` : '';
      tableRows.push(m(
        'tr',
        m('td.name', {title: row.description}, `${row.name}${idx}`, help),
        m('td', `${row.value}`),
        m('td', `${row.severity} (${row.source})`),
      ));
    }

    return m(
      `section${attrs.cssClass}`,
      m('h2', attrs.title),
      m('h3', attrs.subTitle),
      m(
        'table',
        m('thead',
          m('tr', m('td', 'Name'), m('td', 'Value'), m('td', 'Type'))),
        m('tbody', tableRows),
      ),
    );
  }
}

class MetricErrors implements m.ClassComponent {
  view() {
    if (!globals.metricError) return;
    return m(
      `section.errors`,
      m('h2', `Metric Errors`),
      m('h3', `One or more metrics were not computed successfully:`),
      m('div.metric-error', globals.metricError));
  }
}

class TraceMetadata implements m.ClassComponent {
  private queryResponse?: QueryResponse;

  constructor() {
    const engine = getEngine('StatsSection');
    if (engine === undefined) {
      return;
    }
    const query = `with 
          metadata_with_priorities as (select
            name, ifnull(str_value, cast(int_value as text)) as value,
            name in (
               "trace_size_bytes", 
               "cr-os-arch",
               "cr-os-name",
               "cr-os-version",
               "cr-physical-memory",
               "cr-product-version",
               "cr-hardware-class"
            ) as priority 
            from metadata
          )
          select name, value
          from metadata_with_priorities 
          order by priority desc, name`;
    runQuery(query, engine).then((resp: QueryResponse) => {
      this.queryResponse = resp;
      raf.scheduleFullRedraw();
    });
  }


  view() {
    const resp = this.queryResponse;
    if (resp === undefined || resp.totalRowCount === 0) {
      return m('');
    }

    const tableRows = [];
    for (const row of resp.rows) {
      tableRows.push(m(
        'tr',
        m('td.name', `${row.name}`),
        m('td', `${row.value}`),
      ));
    }

    return m(
      'section',
      m('h2', 'System info and metadata'),
      m(
        'table',
        m('thead', m('tr', m('td', 'Name'), m('td', 'Value'))),
        m('tbody', tableRows),
      ),
    );
  }
}

class AndroidGameInterventionList implements m.ClassComponent {
  private queryResponse?: QueryResponse;

  constructor() {
    const engine = getEngine('StatsSection');
    if (engine === undefined) {
      return;
    }
    const query = `select
                package_name,
                uid,
                current_mode,
                standard_mode_supported,
                standard_mode_downscale,
                standard_mode_use_angle,
                standard_mode_fps,
                perf_mode_supported,
                perf_mode_downscale,
                perf_mode_use_angle,
                perf_mode_fps,
                battery_mode_supported,
                battery_mode_downscale,
                battery_mode_use_angle,
                battery_mode_fps
                from android_game_intervention_list`;
    runQuery(query, engine).then((resp: QueryResponse) => {
      this.queryResponse = resp;
      raf.scheduleFullRedraw();
    });
  }


  view() {
    const resp = this.queryResponse;
    if (resp === undefined || resp.totalRowCount === 0) {
      return m('');
    }

    const tableRows = [];
    let standardInterventions = '';
    let perfInterventions = '';
    let batteryInterventions = '';
    for (const row of resp.rows) {
      // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
      if (row.standard_mode_supported) {
        standardInterventions =
            `angle=${row.standard_mode_use_angle},downscale=${
              row.standard_mode_downscale},fps=${row.standard_mode_fps}`;
      } else {
        standardInterventions = 'Not supported';
      }

      // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
      if (row.perf_mode_supported) {
        perfInterventions = `angle=${row.perf_mode_use_angle},downscale=${
          row.perf_mode_downscale},fps=${row.perf_mode_fps}`;
      } else {
        perfInterventions = 'Not supported';
      }

      // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
      if (row.battery_mode_supported) {
        batteryInterventions = `angle=${row.battery_mode_use_angle},downscale=${
          row.battery_mode_downscale},fps=${row.battery_mode_fps}`;
      } else {
        batteryInterventions = 'Not supported';
      }
      // Game mode numbers are defined in
      // https://cs.android.com/android/platform/superproject/+/main:frameworks/base/core/java/android/app/GameManager.java;l=68
      if (row.current_mode === 1) {
        row.current_mode = 'Standard';
      } else if (row.current_mode === 2) {
        row.current_mode = 'Performance';
      } else if (row.current_mode === 3) {
        row.current_mode = 'Battery';
      }
      tableRows.push(m(
        'tr',
        m('td.name', `${row.package_name}`),
        m('td', `${row.current_mode}`),
        m('td', standardInterventions),
        m('td', perfInterventions),
        m('td', batteryInterventions),
      ));
    }

    return m(
      'section',
      m('h2', 'Game Intervention List'),
      m(
        'table',
        m('thead',
          m(
            'tr',
            m('td', 'Name'),
            m('td', 'Current mode'),
            m('td', 'Standard mode interventions'),
            m('td', 'Performance mode interventions'),
            m('td', 'Battery mode interventions'),
          )),
        m('tbody', tableRows),
      ),
    );
  }
}

class PackageList implements m.ClassComponent {
  private queryResponse?: QueryResponse;

  constructor() {
    const engine = getEngine('StatsSection');
    if (engine === undefined) {
      return;
    }
    const query = `select package_name, version_code, debuggable,
                profileable_from_shell from package_list`;
    runQuery(query, engine).then((resp: QueryResponse) => {
      this.queryResponse = resp;
      raf.scheduleFullRedraw();
    });
  }


  view() {
    const resp = this.queryResponse;
    if (resp === undefined || resp.totalRowCount === 0) {
      return m('');
    }

    const tableRows = [];
    for (const row of resp.rows) {
      tableRows.push(m(
        'tr',
        m('td.name', `${row.package_name}`),
        m('td', `${row.version_code}`),
        /* eslint-disable @typescript-eslint/strict-boolean-expressions */
        m('td',
          `${row.debuggable ? 'debuggable' : ''} ${
            row.profileable_from_shell ? 'profileable' : ''}`),
        /* eslint-enable */
      ));
    }

    return m(
      'section',
      m('h2', 'Package list'),
      m(
        'table',
        m('thead',
          m('tr',
            m('td', 'Name'),
            m('td', 'Version code'),
            m('td', 'Flags'))),
        m('tbody', tableRows),
      ),
    );
  }
}

export const TraceInfoPage = createPage({
  view() {
    return m(
      '.trace-info-page',
      m(MetricErrors),
      m(StatsSection, {
        queryId: 'info_errors',
        title: 'Import errors',
        cssClass: '.errors',
        subTitle:
              `The following errors have been encountered while importing the
               trace. These errors are usually non-fatal but indicate that one
               or more tracks might be missing or showing erroneous data.`,
        sqlConstraints: `severity = 'error' and value > 0`,

      }),
      m(StatsSection, {
        queryId: 'info_data_losses',
        title: 'Data losses',
        cssClass: '.errors',
        subTitle:
              `These counters are collected at trace recording time. The trace
               data for one or more data sources was dropped and hence some
               track contents will be incomplete.`,
        sqlConstraints: `severity = 'data_loss' and value > 0`,
      }),
      m(TraceMetadata),
      m(PackageList),
      m(AndroidGameInterventionList),
      m(StatsSection, {
        queryId: 'info_all',
        title: 'Debugging stats',
        cssClass: '',
        subTitle: `Debugging statistics such as trace buffer usage and metrics
                     coming from the TraceProcessor importer stages.`,
        sqlConstraints: '',

      }),
    );
  },
});
