// Copyright 2019 The Chromium Authors
// 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));
};
