import LicensePage from './licensing/LicensePage';
import ReportsList from './reports/ReportsListPage';
import ReportsUpgrade from './reports/ReportsUpgradePage';
import ReportsSettings from './reports/ReportsSettingsPage';
import ReportPage from './reports/ReportPage';
import CSVExportPage from './reports/CSVExportPage';
import reportsReducers from './reports/state/reducers';
import { initReporting } from './reports';
import dataSourcePermissionReducers from './permissions/state/reducers';
import DatasourcePermissions from './permissions/AccessControlDataSourcePermissions';
import DatasourcePermissionsUpgradePage from './permissions/UpgradePage';
import LegacyDataSourcePermissions from './permissions/DataSourcePermissions';
import DataSourceCache from './caching/DataSourceCache';
import DataSourceCacheUpgradePage from './caching/UpgradePage';
import dataSourceCacheReducers from './caching/state/reducers';
import { addRootReducer } from 'app/store/configureStore';
import { initWhitelabeling } from './whitelabeling';
import { initLicenseWarnings } from './licensing';
import { initMetaAnalytics } from './meta-analytics';
import { config, featureEnabled, reportExperimentView } from '@grafana/runtime';
import DataSourceInsights from './meta-analytics/DataSourceInsights/DataSourceInsights';
import DataSourceInsightsUpgradePage from './meta-analytics/DataSourceInsights/UpgradePage';
import metaAnalyticsReducers from './meta-analytics/state/reducers';
import { extraRoutes } from 'app/routes/routes';
import { AccessControlAction, DashboardRoutes } from 'app/types';
import { contextSrv } from 'app/core/core';
import { initPageBanners } from './banners';
import { initRecordedQueries } from './recorded-queries';
import { recordedQueryReducer } from './recorded-queries/state/reducers';
import { initEnterpriseAdmin } from './admin';
import { RecordedQueriesConfig } from './recorded-queries/RecordedQueriesConfig';
import { WriteTargetConfig } from './recorded-queries/WriteTargetConfig';
import { buildExperimentID, ExperimentGroup } from './utils/featureHighlights';
import { AccessControlAction as EnterpriseAccessControlAction } from './types';

export function addExtensionReducers() {
  if (featureEnabled('dspermissions')) {
    addRootReducer(dataSourcePermissionReducers);
  }

  if (featureEnabled('caching')) {
    addRootReducer(dataSourceCacheReducers);
  }

  if (featureEnabled('reports')) {
    addRootReducer(reportsReducers);
  }

  if (featureEnabled('analytics')) {
    addRootReducer(metaAnalyticsReducers);
  }

  if (featureEnabled('recordedqueries')) {
    addRootReducer(recordedQueryReducer);
  }
}

function initEnterprise() {
  const highlightsEnabled = config.featureToggles.featureHighlights;
  initLicenseWarnings();
  initReporting();
  initMetaAnalytics();

  if (featureEnabled('whitelabeling')) {
    initWhitelabeling();
  }

  if (featureEnabled('recordedqueries')) {
    initRecordedQueries();
  }

  if (featureEnabled('admin')) {
    initEnterpriseAdmin();
  }

  // DataSources components
  if (featureEnabled('caching')) {
    extraRoutes.push({
      path: '/datasources/edit/:uid/cache',
      component: DataSourceCache,
    });
  } else if (highlightsEnabled) {
    extraRoutes.push({
      path: '/datasources/edit/:uid/cache/upgrade',
      component: DataSourceCacheUpgradePage,
    });
  }

  if (featureEnabled('analytics')) {
    extraRoutes.push({
      path: '/datasources/edit/:uid/insights',
      component: DataSourceInsights as any,
    });
  } else if (highlightsEnabled) {
    extraRoutes.push({
      path: '/datasources/edit/:uid/insights/upgrade',
      component: DataSourceInsightsUpgradePage,
    });
  }

  const permissionsPath = '/datasources/edit/:uid/permissions';
  if (featureEnabled('dspermissions') && contextSrv.hasPermission(AccessControlAction.DataSourcesPermissionsRead)) {
    if (config.featureToggles['accesscontrol']) {
      extraRoutes.push({
        path: permissionsPath,
        component: DatasourcePermissions,
      });
    } else {
      extraRoutes.push({
        path: permissionsPath,
        component: LegacyDataSourcePermissions,
      });
    }
  } else if (highlightsEnabled) {
    extraRoutes.push({
      path: permissionsPath + '/upgrade',
      component: DatasourcePermissionsUpgradePage,
    });
  }

  if (featureEnabled('reports')) {
    extraRoutes.push(
      {
        path: '/reports',
        component: ReportsList,
      },
      {
        path: '/reports/edit/:id',
        component: ReportPage as any,
      },
      {
        path: '/reports/settings',
        component: ReportsSettings,
      }
    );
  } else if (highlightsEnabled) {
    extraRoutes.push({
      path: '/reports',
      component: ReportsUpgrade,
    });
  }

  if (featureEnabled('reports')) {
    extraRoutes.push({
      path: '/d-csv/:uid',
      pageClass: 'dashboard-solo',
      routeName: DashboardRoutes.Normal,
      component: CSVExportPage,
    });
  }

  const showRecordQuery = featureEnabled('recordedqueries') && config?.recordedQueries?.enabled;
  if (contextSrv.isEditor && showRecordQuery) {
    extraRoutes.push(
      ...[
        {
          path: '/recorded-queries',
          component: RecordedQueriesConfig,
        },
        {
          path: '/recorded-queries/write-target',
          component: WriteTargetConfig,
        },
      ]
    );
  }

  if (featureEnabled('reports.creation')) {
    extraRoutes.push({
      path: '/reports/new',
      component: ReportPage as any,
    });
  }
}

// initUnlicensed initialized features which are defined in Enterprise but
// should be available when running without a license.
function initUnlicensed() {
  initPageBanners();

  extraRoutes.push({
    path: '/admin/licensing',
    roles: () =>
      contextSrv.evaluatePermission(
        () => ['ServerAdmin'],
        [EnterpriseAccessControlAction.LicensingRead, AccessControlAction.ActionServerStatsRead]
      ),
    component: LicensePage,
  });

  // Report experimentation views
  if (contextSrv.isSignedIn && config.licenseInfo.stateInfo !== 'Licensed') {
    reportExperimentView(
      buildExperimentID(),
      config.featureToggles.featureHighlights ? ExperimentGroup.Test : ExperimentGroup.Control,
      ''
    );
  }
}

export function init() {
  initUnlicensed();
  initEnterprise();
}
