// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {combineReducers} from 'redux';
import {createSelector} from 'reselect';
import {createReducer, createRequestReducer} from './redux-helpers.js';
import * as permissions from 'reducers/permissions.js';
import {fieldTypes, SITEWIDE_DEFAULT_COLUMNS, defaultIssueFieldMap,
  parseColSpec, stringValuesForIssueField} from 'shared/issue-fields.js';
import {hasPrefix, removePrefix} from 'shared/helpers.js';
import {fieldNameToLabelPrefix,
  labelNameToLabelPrefixes, labelNameToLabelValue, fieldDefToName,
  restrictionLabelsForPermissions} from 'shared/convertersV0.js';
import {prpcClient} from 'prpc-client-instance.js';
import 'shared/typedef.js';

/** @typedef {import('redux').AnyAction} AnyAction */

// Actions
export const SELECT = 'projectV0/SELECT';

const FETCH_CONFIG_START = 'projectV0/FETCH_CONFIG_START';
export const FETCH_CONFIG_SUCCESS = 'projectV0/FETCH_CONFIG_SUCCESS';
const FETCH_CONFIG_FAILURE = 'projectV0/FETCH_CONFIG_FAILURE';

export const FETCH_PRESENTATION_CONFIG_START =
  'projectV0/FETCH_PRESENTATION_CONFIG_START';
export const FETCH_PRESENTATION_CONFIG_SUCCESS =
  'projectV0/FETCH_PRESENTATION_CONFIG_SUCCESS';
export const FETCH_PRESENTATION_CONFIG_FAILURE =
  'projectV0/FETCH_PRESENTATION_CONFIG_FAILURE';

export const FETCH_CUSTOM_PERMISSIONS_START =
  'projectV0/FETCH_CUSTOM_PERMISSIONS_START';
export const FETCH_CUSTOM_PERMISSIONS_SUCCESS =
  'projectV0/FETCH_CUSTOM_PERMISSIONS_SUCCESS';
export const FETCH_CUSTOM_PERMISSIONS_FAILURE =
  'projectV0/FETCH_CUSTOM_PERMISSIONS_FAILURE';


export const FETCH_VISIBLE_MEMBERS_START =
  'projectV0/FETCH_VISIBLE_MEMBERS_START';
export const FETCH_VISIBLE_MEMBERS_SUCCESS =
  'projectV0/FETCH_VISIBLE_MEMBERS_SUCCESS';
export const FETCH_VISIBLE_MEMBERS_FAILURE =
  'projectV0/FETCH_VISIBLE_MEMBERS_FAILURE';

const FETCH_TEMPLATES_START = 'projectV0/FETCH_TEMPLATES_START';
export const FETCH_TEMPLATES_SUCCESS = 'projectV0/FETCH_TEMPLATES_SUCCESS';
const FETCH_TEMPLATES_FAILURE = 'projectV0/FETCH_TEMPLATES_FAILURE';

/* State Shape
{
  name: string,

  configs: Object<string, Config>,
  presentationConfigs: Object<string, PresentationConfig>,
  customPermissions: Object<string, Array<string>>,
  visibleMembers:
      Object<string, {userRefs: Array<UserRef>, groupRefs: Array<UserRef>}>,
  templates: Object<string, Array<TemplateDef>>,
  presentationConfigsLoaded: Object<string, boolean>,

  requests: {
    fetchConfig: ReduxRequestState,
    fetchMembers: ReduxRequestState
    fetchCustomPermissions: ReduxRequestState,
    fetchPresentationConfig: ReduxRequestState,
    fetchTemplates: ReduxRequestState,
  },
}
*/

// Reducers
export const nameReducer = createReducer(null, {
  [SELECT]: (_state, {projectName}) => projectName,
});

export const configsReducer = createReducer({}, {
  [FETCH_CONFIG_SUCCESS]: (state, {projectName, config}) => ({
    ...state,
    [projectName]: config,
  }),
});

export const presentationConfigsReducer = createReducer({}, {
  [FETCH_PRESENTATION_CONFIG_SUCCESS]:
    (state, {projectName, presentationConfig}) => ({
      ...state,
      [projectName]: presentationConfig,
    }),
});

/**
 * Adds custom permissions to Redux in a normalized state.
 * @param {Object<string, Array<String>>} state Redux state.
 * @param {AnyAction} Action
 * @return {Object<string, Array<String>>}
 */
export const customPermissionsReducer = createReducer({}, {
  [FETCH_CUSTOM_PERMISSIONS_SUCCESS]:
    (state, {projectName, permissions}) => ({
      ...state,
      [projectName]: permissions,
    }),
});

export const visibleMembersReducer = createReducer({}, {
  [FETCH_VISIBLE_MEMBERS_SUCCESS]: (state, {projectName, visibleMembers}) => ({
    ...state,
    [projectName]: visibleMembers,
  }),
});

export const templatesReducer = createReducer({}, {
  [FETCH_TEMPLATES_SUCCESS]: (state, {projectName, templates}) => ({
    ...state,
    [projectName]: templates,
  }),
});

const requestsReducer = combineReducers({
  fetchConfig: createRequestReducer(
      FETCH_CONFIG_START, FETCH_CONFIG_SUCCESS, FETCH_CONFIG_FAILURE),
  fetchMembers: createRequestReducer(
      FETCH_VISIBLE_MEMBERS_START,
      FETCH_VISIBLE_MEMBERS_SUCCESS,
      FETCH_VISIBLE_MEMBERS_FAILURE),
  fetchCustomPermissions: createRequestReducer(
      FETCH_CUSTOM_PERMISSIONS_START,
      FETCH_CUSTOM_PERMISSIONS_SUCCESS,
      FETCH_CUSTOM_PERMISSIONS_FAILURE),
  fetchPresentationConfig: createRequestReducer(
      FETCH_PRESENTATION_CONFIG_START,
      FETCH_PRESENTATION_CONFIG_SUCCESS,
      FETCH_PRESENTATION_CONFIG_FAILURE),
  fetchTemplates: createRequestReducer(
      FETCH_TEMPLATES_START, FETCH_TEMPLATES_SUCCESS, FETCH_TEMPLATES_FAILURE),
});

export const reducer = combineReducers({
  name: nameReducer,
  configs: configsReducer,
  customPermissions: customPermissionsReducer,
  presentationConfigs: presentationConfigsReducer,
  visibleMembers: visibleMembersReducer,
  templates: templatesReducer,
  requests: requestsReducer,
});

// Selectors
export const project = (state) => state.projectV0 || {};

export const viewedProjectName =
  createSelector(project, (project) => project.name || null);

export const configs =
  createSelector(project, (project) => project.configs || {});
export const presentationConfigs =
  createSelector(project, (project) => project.presentationConfigs || {});
export const customPermissions =
  createSelector(project, (project) => project.customPermissions || {});
export const visibleMembers =
  createSelector(project, (project) => project.visibleMembers || {});
export const templates =
  createSelector(project, (project) => project.templates || {});

export const viewedConfig = createSelector(
    [viewedProjectName, configs],
    (projectName, configs) => configs[projectName] || {});
export const viewedPresentationConfig = createSelector(
    [viewedProjectName, presentationConfigs],
    (projectName, configs) => configs[projectName] || {});

// TODO(crbug.com/monorail/7080): Come up with a more clear and
// consistent pattern for determining when data is loaded.
export const viewedPresentationConfigLoaded = createSelector(
    [viewedProjectName, presentationConfigs],
    (projectName, configs) => !!configs[projectName]);
export const viewedCustomPermissions = createSelector(
    [viewedProjectName, customPermissions],
    (projectName, permissions) => permissions[projectName] || []);
export const viewedVisibleMembers = createSelector(
    [viewedProjectName, visibleMembers],
    (projectName, visibleMembers) => visibleMembers[projectName] || {});
export const viewedTemplates = createSelector(
    [viewedProjectName, templates],
    (projectName, templates) => templates[projectName] || []);

/**
 * Get the default columns for the currently viewed project.
 */
export const defaultColumns = createSelector(viewedPresentationConfig,
    ({defaultColSpec}) =>{
      if (defaultColSpec) {
        return parseColSpec(defaultColSpec);
      }
      return SITEWIDE_DEFAULT_COLUMNS;
    });


/**
 * Get the default query for the currently viewed project.
 */
export const defaultQuery = createSelector(viewedPresentationConfig,
    (config) => config.defaultQuery || '');

// Look up components by path.
export const componentsMap = createSelector(
    viewedConfig,
    (config) => {
      if (!config || !config.componentDefs) return new Map();
      const acc = new Map();
      for (const v of config.componentDefs) {
        acc.set(v.path, v);
      }
      return acc;
    },
);

export const fieldDefs = createSelector(
    viewedConfig, (config) => ((config && config.fieldDefs) || []),
);

export const fieldDefMap = createSelector(
    fieldDefs, (fieldDefs) => {
      const map = new Map();
      fieldDefs.forEach((fd) => {
        map.set(fd.fieldRef.fieldName.toLowerCase(), fd);
      });
      return map;
    },
);

export const labelDefs = createSelector(
    [viewedConfig, viewedCustomPermissions],
    (config, permissions) => [
      ...((config && config.labelDefs) || []),
      ...restrictionLabelsForPermissions(permissions),
    ],
);

// labelDefs stored in an easily findable format with label names as keys.
export const labelDefMap = createSelector(
    labelDefs, (labelDefs) => {
      const map = new Map();
      labelDefs.forEach((ld) => {
        map.set(ld.label.toLowerCase(), ld);
      });
      return map;
    },
);

/**
 * A selector that builds a map where keys are label prefixes
 * and values equal to sets of possible values corresponding to the prefix
 * @param {Object} state Current Redux state.
 * @return {Map}
 */
export const labelPrefixValueMap = createSelector(labelDefs, (labelDefs) => {
  const prefixMap = new Map();
  labelDefs.forEach((ld) => {
    const prefixes = labelNameToLabelPrefixes(ld.label);

    prefixes.forEach((prefix) => {
      if (prefixMap.has(prefix)) {
        prefixMap.get(prefix).add(labelNameToLabelValue(ld.label, prefix));
      } else {
        prefixMap.set(prefix, new Set(
            [labelNameToLabelValue(ld.label, prefix)]));
      }
    });
  });

  return prefixMap;
});

/**
 * A selector that builds an array of label prefixes, keeping casing intact
 * Some labels are implicitly used as custom fields in the grid and list view.
 * Only labels with more than one option are included, to reduce noise.
 * @param {Object} state Current Redux state.
 * @return {Array}
 */
export const labelPrefixFields = createSelector(
    labelPrefixValueMap, (map) => {
      const prefixes = [];

      map.forEach((options, prefix) => {
      // Ignore label prefixes with only one value.
        if (options.size > 1) {
          prefixes.push(prefix);
        }
      });

      return prefixes;
    },
);

/**
 * A selector that wraps labelPrefixFields arrays as set for fast lookup.
 * @param {Object} state Current Redux state.
 * @return {Set}
 */
export const labelPrefixSet = createSelector(
    labelPrefixFields, (fields) => new Set(fields.map(
        (field) => field.toLowerCase())),
);

export const enumFieldDefs = createSelector(
    fieldDefs,
    (fieldDefs) => {
      return fieldDefs.filter(
          (fd) => fd.fieldRef.type === fieldTypes.ENUM_TYPE);
    },
);

/**
 * A selector that builds a function that's used to compute the value of
 * a given field name on a given issue. This function abstracts the difference
 * between custom fields, built-in fields, and implicit fields created
 * from labels and considers these values in the context of the current
 * project configuration.
 * @param {Object} state Current Redux state.
 * @return {function(Issue, string): Array<string>} A function that processes a
 *   given issue and field name to find the string value for that field, in
 *   the issue.
 */
export const extractFieldValuesFromIssue = createSelector(
    viewedProjectName,
    (projectName) => (issue, fieldName) =>
      stringValuesForIssueField(issue, fieldName, projectName),
);

/**
 * A selector that builds a function that's used to compute the type of a given
 * field name.
 * @param {Object} state Current Redux state.
 * @return {function(string): string}
 */
export const extractTypeForFieldName = createSelector(fieldDefMap,
    (fieldDefMap) => {
      return (fieldName) => {
        const key = fieldName.toLowerCase();

        // If the field is a built in field. Default fields have precedence
        // over custom fields.
        if (defaultIssueFieldMap.hasOwnProperty(key)) {
          return defaultIssueFieldMap[key].type;
        }

        // If the field is a custom field. Custom fields have precedence
        // over label prefixes.
        if (fieldDefMap.has(key)) {
          return fieldDefMap.get(key).fieldRef.type;
        }

        // Default to STR_TYPE, including for label fields.
        return fieldTypes.STR_TYPE;
      };
    },
);

export const optionsPerEnumField = createSelector(
    enumFieldDefs,
    labelDefs,
    (fieldDefs, labelDefs) => {
      const map = new Map(fieldDefs.map(
          (fd) => [fd.fieldRef.fieldName.toLowerCase(), []]));
      labelDefs.forEach((ld) => {
        const labelName = ld.label;

        const fd = fieldDefs.find((fd) => hasPrefix(
            labelName, fieldNameToLabelPrefix(fd.fieldRef.fieldName)));
        if (fd) {
          const key = fd.fieldRef.fieldName.toLowerCase();
          map.get(key).push({
            ...ld,
            optionName: removePrefix(labelName,
                fieldNameToLabelPrefix(fd.fieldRef.fieldName)),
          });
        }
      });
      return map;
    },
);

export const fieldDefsForPhases = createSelector(
    fieldDefs,
    (fieldDefs) => {
      if (!fieldDefs) return [];
      return fieldDefs.filter((f) => f.isPhaseField);
    },
);

export const fieldDefsByApprovalName = createSelector(
    fieldDefs,
    (fieldDefs) => {
      if (!fieldDefs) return new Map();
      const acc = new Map();
      for (const fd of fieldDefs) {
        if (fd.fieldRef && fd.fieldRef.approvalName) {
          if (acc.has(fd.fieldRef.approvalName)) {
            acc.get(fd.fieldRef.approvalName).push(fd);
          } else {
            acc.set(fd.fieldRef.approvalName, [fd]);
          }
        }
      }
      return acc;
    },
);

export const fetchingConfig = (state) => {
  return state.projectV0.requests.fetchConfig.requesting;
};

/**
 * Shorthand method for detecting whether we are currently
 * fetching presentationConcifg
 * @param {Object} state Current Redux state.
 * @return {boolean}
 */
export const fetchingPresentationConfig = (state) => {
  return state.projectV0.requests.fetchPresentationConfig.requesting;
};

// Action Creators
/**
 * Action creator to set the currently viewed Project.
 * @param {string} projectName The name of the Project to select.
 * @return {function(function): Promise<void>}
 */
export const select = (projectName) => {
  return (dispatch) => dispatch({type: SELECT, projectName});
};

/**
 * Fetches data required to view project.
 * @param {string} projectName
 * @return {function(function): Promise<void>}
 */
export const fetch = (projectName) => async (dispatch) => {
  const configPromise = dispatch(fetchConfig(projectName));
  const visibleMembersPromise = dispatch(fetchVisibleMembers(projectName));

  dispatch(fetchPresentationConfig(projectName));
  dispatch(fetchTemplates(projectName));

  const customPermissionsPromise = dispatch(
      fetchCustomPermissions(projectName));

  // TODO(crbug.com/monorail/5828): Remove window.TKR_populateAutocomplete once
  // the old autocomplete code is deprecated.
  const [config, visibleMembers, customPermissions] = await Promise.all([
    configPromise,
    visibleMembersPromise,
    customPermissionsPromise]);
  config.labelDefs = [...config.labelDefs,
    ...restrictionLabelsForPermissions(customPermissions)];
  dispatch(fetchFieldPerms(config.projectName, config.fieldDefs));
  // eslint-disable-next-line new-cap
  window.TKR_populateAutocomplete(config, visibleMembers, customPermissions);
};

/**
 * Fetches project configuration including things like the custom fields in a
 * project, the statuses, etc.
 * @param {string} projectName
 * @return {function(function): Promise<Config>}
 */
const fetchConfig = (projectName) => async (dispatch) => {
  dispatch({type: FETCH_CONFIG_START});

  const getConfig = prpcClient.call(
      'monorail.Projects', 'GetConfig', {projectName});

  try {
    const config = await getConfig;
    dispatch({type: FETCH_CONFIG_SUCCESS, projectName, config});
    return config;
  } catch (error) {
    dispatch({type: FETCH_CONFIG_FAILURE, error});
  }
};

export const fetchPresentationConfig = (projectName) => async (dispatch) => {
  dispatch({type: FETCH_PRESENTATION_CONFIG_START});

  try {
    const presentationConfig = await prpcClient.call(
        'monorail.Projects', 'GetPresentationConfig', {projectName});
    dispatch({
      type: FETCH_PRESENTATION_CONFIG_SUCCESS,
      projectName,
      presentationConfig,
    });
  } catch (error) {
    dispatch({type: FETCH_PRESENTATION_CONFIG_FAILURE, error});
  }
};

/**
 * Fetches custom permissions defined for a project.
 * @param {string} projectName
 * @return {function(function): Promise<Array<string>>}
 */
export const fetchCustomPermissions = (projectName) => async (dispatch) => {
  dispatch({type: FETCH_CUSTOM_PERMISSIONS_START});

  try {
    const {permissions} = await prpcClient.call(
        'monorail.Projects', 'GetCustomPermissions', {projectName});
    dispatch({
      type: FETCH_CUSTOM_PERMISSIONS_SUCCESS,
      projectName,
      permissions,
    });
    return permissions;
  } catch (error) {
    dispatch({type: FETCH_CUSTOM_PERMISSIONS_FAILURE, error});
  }
};

/**
 * Fetches the project members that the user is able to view.
 * @param {string} projectName
 * @return {function(function): Promise<GetVisibleMembersResponse>}
 */
export const fetchVisibleMembers = (projectName) => async (dispatch) => {
  dispatch({type: FETCH_VISIBLE_MEMBERS_START});

  try {
    const visibleMembers = await prpcClient.call(
        'monorail.Projects', 'GetVisibleMembers', {projectName});
    dispatch({
      type: FETCH_VISIBLE_MEMBERS_SUCCESS,
      projectName,
      visibleMembers,
    });
    return visibleMembers;
  } catch (error) {
    dispatch({type: FETCH_VISIBLE_MEMBERS_FAILURE, error});
  }
};

const fetchTemplates = (projectName) => async (dispatch) => {
  dispatch({type: FETCH_TEMPLATES_START});

  const listTemplates = prpcClient.call(
      'monorail.Projects', 'ListProjectTemplates', {projectName});

  // TODO(zhangtiff): Remove (see above TODO).
  if (!listTemplates) return;

  try {
    const resp = await listTemplates;
    dispatch({
      type: FETCH_TEMPLATES_SUCCESS,
      projectName,
      templates: resp.templates,
    });
  } catch (error) {
    dispatch({type: FETCH_TEMPLATES_FAILURE, error});
  }
};

// Helpers

/**
 * Helper to fetch field permissions.
 * @param {string} projectName The name of the project where the fields are.
 * @param {Array<FieldDef>} fieldDefs
 * @return {function(function): Promise<void>}
 */
export const fetchFieldPerms = (projectName, fieldDefs) => async (dispatch) => {
  const fieldDefsNames = [];
  if (fieldDefs) {
    fieldDefs.forEach((fd) => {
      const fieldDefName = fieldDefToName(projectName, fd);
      fieldDefsNames.push(fieldDefName);
    });
  }
  await dispatch(permissions.batchGet(fieldDefsNames));
};
