// 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 {prpcClient} from 'prpc-client-instance.js';
import {objectToMap} from 'shared/helpers.js';
import {userRefToId, userToUserRef} from 'shared/convertersV0.js';
import loadGapi, {fetchGapiEmail} from 'shared/gapi-loader.js';
import {DEFAULT_MD_PROJECTS} from 'shared/md-helper.js';
import {viewedProjectName} from 'reducers/projectV0.js';

// Actions
const FETCH_START = 'userV0/FETCH_START';
const FETCH_SUCCESS = 'userV0/FETCH_SUCCESS';
const FETCH_FAILURE = 'userV0/FETCH_FAILURE';

export const FETCH_PROJECTS_START = 'userV0/FETCH_PROJECTS_START';
export const FETCH_PROJECTS_SUCCESS = 'userV0/FETCH_PROJECTS_SUCCESS';
export const FETCH_PROJECTS_FAILURE = 'userV0/FETCH_PROJECTS_FAILURE';

const FETCH_HOTLISTS_START = 'userV0/FETCH_HOTLISTS_START';
const FETCH_HOTLISTS_SUCCESS = 'userV0/FETCH_HOTLISTS_SUCCESS';
const FETCH_HOTLISTS_FAILURE = 'userV0/FETCH_HOTLISTS_FAILURE';

const FETCH_PREFS_START = 'userV0/FETCH_PREFS_START';
const FETCH_PREFS_SUCCESS = 'userV0/FETCH_PREFS_SUCCESS';
const FETCH_PREFS_FAILURE = 'userV0/FETCH_PREFS_FAILURE';

export const SET_PREFS_START = 'userV0/SET_PREFS_START';
export const SET_PREFS_SUCCESS = 'userV0/SET_PREFS_SUCCESS';
export const SET_PREFS_FAILURE = 'userV0/SET_PREFS_FAILURE';

const GAPI_LOGIN_START = 'GAPI_LOGIN_START';
export const GAPI_LOGIN_SUCCESS = 'GAPI_LOGIN_SUCCESS';
const GAPI_LOGIN_FAILURE = 'GAPI_LOGIN_FAILURE';

const GAPI_LOGOUT_START = 'GAPI_LOGOUT_START';
export const GAPI_LOGOUT_SUCCESS = 'GAPI_LOGOUT_SUCCESS';
const GAPI_LOGOUT_FAILURE = 'GAPI_LOGOUT_FAILURE';


// Monorial UserPrefs are stored as plain strings in Monorail's backend.
// We want boolean preferences to be converted into booleans for convenience.
// Currently, there are no user prefs in Monorail that are NOT booleans, so
// we default to converting all user prefs to booleans unless otherwise
// specified.
// See: https://source.chromium.org/chromium/infra/infra/+/main:appengine/monorail/framework/framework_bizobj.py;l=409
const NON_BOOLEAN_PREFS = new Set(['test_non_bool']);


/* State Shape
{
  currentUser: {
    ...user: Object,
    groups: Array,
    hotlists: Array,
    prefs: Object,
    gapiEmail: String,
  },
  requests: {
    fetch: Object,
    fetchHotlists: Object,
    fetchPrefs: Object,
  },
}
*/

// Reducers
const USER_DEFAULT = {
  groups: [],
  hotlists: [],
  projects: {},
  prefs: {},
  prefsLoaded: false,
};

const gapiEmailReducer = (user, action) => {
  return {
    ...user,
    gapiEmail: action.email || '',
  };
};

export const currentUserReducer = createReducer(USER_DEFAULT, {
  [FETCH_SUCCESS]: (_user, action) => {
    return {
      ...USER_DEFAULT,
      ...action.user,
      groups: action.groups,
    };
  },
  [FETCH_HOTLISTS_SUCCESS]: (user, action) => {
    return {...user, hotlists: action.hotlists};
  },
  [FETCH_PREFS_SUCCESS]: (user, action) => {
    return {
      ...user,
      prefs: action.prefs,
      prefsLoaded: true,
    };
  },
  [SET_PREFS_SUCCESS]: (user, action) => {
    const newPrefs = action.newPrefs;
    const prefs = Object.assign({}, user.prefs);
    newPrefs.forEach(({name, value}) => {
      prefs[name] = value;
    });
    return {
      ...user,
      prefs,
    };
  },
  [GAPI_LOGIN_SUCCESS]: gapiEmailReducer,
  [GAPI_LOGOUT_SUCCESS]: gapiEmailReducer,
});

export const usersByIdReducer = createReducer({}, {
  [FETCH_PROJECTS_SUCCESS]: (state, action) => {
    const newState = {...state};

    action.usersProjects.forEach((userProjects) => {
      const {userRef, ownerOf = [], memberOf = [], contributorTo = [],
        starredProjects = []} = userProjects;

      const userId = userRefToId(userRef);

      newState[userId] = {
        ...newState[userId],
        projects: {
          ownerOf,
          memberOf,
          contributorTo,
          starredProjects,
        },
      };
    });

    return newState;
  },
});

const requestsReducer = combineReducers({
  // Request for getting backend metadata related to a user, such as
  // which groups they belong to and whether they're a site admin.
  fetch: createRequestReducer(FETCH_START, FETCH_SUCCESS, FETCH_FAILURE),
  // Requests for fetching projects a user is related to.
  fetchProjects: createRequestReducer(
      FETCH_PROJECTS_START, FETCH_PROJECTS_SUCCESS, FETCH_PROJECTS_FAILURE),
  // Request for getting a user's hotlists.
  fetchHotlists: createRequestReducer(
      FETCH_HOTLISTS_START, FETCH_HOTLISTS_SUCCESS, FETCH_HOTLISTS_FAILURE),
  // Request for getting a user's prefs.
  fetchPrefs: createRequestReducer(
      FETCH_PREFS_START, FETCH_PREFS_SUCCESS, FETCH_PREFS_FAILURE),
  // Request for setting a user's prefs.
  setPrefs: createRequestReducer(
      SET_PREFS_START, SET_PREFS_SUCCESS, SET_PREFS_FAILURE),
});

export const reducer = combineReducers({
  currentUser: currentUserReducer,
  usersById: usersByIdReducer,
  requests: requestsReducer,
});

// Selectors
export const requests = (state) => state.userV0.requests;
export const currentUser = (state) => state.userV0.currentUser || {};
// TODO(zhangtiff): Replace custom logic to check if the user is logged in
// across the frontend.
export const isLoggedIn = createSelector(
    currentUser, (user) => user && user.userId);
export const userRef = createSelector(
    currentUser, (user) => userToUserRef(user));
export const prefs = createSelector(
    currentUser, viewedProjectName, (user, projectName = '') => {
      const prefs = {
        // Make Markdown default to true for projects who have opted in.
        render_markdown: String(DEFAULT_MD_PROJECTS.has(projectName)),
        ...user.prefs
      };
      for (let prefName of Object.keys(prefs)) {
        if (!NON_BOOLEAN_PREFS.has(prefName)) {
          // Monorail user preferences are stored as strings.
          prefs[prefName] = prefs[prefName] === 'true';
        }
      }
      return objectToMap(prefs);
    });

const _usersById = (state) => state.userV0.usersById || {};
export const usersById = createSelector(_usersById,
    (usersById) => objectToMap(usersById));

export const projectsPerUser = createSelector(usersById, (usersById) => {
  const map = new Map();
  for (const [key, value] of usersById.entries()) {
    if (value.projects) {
      map.set(key, value.projects);
    }
  }
  return map;
});

// Projects for just the current user.
export const projects = createSelector(projectsPerUser, userRef,
    (projectsMap, userRef) => projectsMap.get(userRefToId(userRef)) || {});

// Action Creators
/**
 * Fetches the data required to view the logged in user.
 * @param {string} displayName The display name of the logged in user. Note that
 *   while usernames may be hidden for users in Monorail, the logged in user
 *   will always be able to view their own name.
 * @return {function(function): Promise<void>}
 */
export const fetch = (displayName) => async (dispatch) => {
  dispatch({type: FETCH_START});

  const message = {
    userRef: {displayName},
  };

  try {
    const resp = await Promise.all([
      prpcClient.call(
          'monorail.Users', 'GetUser', message),
      prpcClient.call(
          'monorail.Users', 'GetMemberships', message),
    ]);

    const user = resp[0];

    dispatch({
      type: FETCH_SUCCESS,
      user,
      groups: resp[1].groupRefs || [],
    });

    const userRef = userToUserRef(user);

    dispatch(fetchProjects([userRef]));
    const hotlistsPromise = dispatch(fetchHotlists(userRef));
    dispatch(fetchPrefs());

    hotlistsPromise.then((hotlists) => {
      // TODO(crbug.com/monorail/5828): Remove
      // window.TKR_populateHotlistAutocomplete once the old
      // autocomplete code is deprecated.
      window.TKR_populateHotlistAutocomplete(hotlists);
    });
  } catch (error) {
    dispatch({type: FETCH_FAILURE, error});
  };
};

export const fetchProjects = (userRefs) => async (dispatch) => {
  dispatch({type: FETCH_PROJECTS_START});
  try {
    const resp = await prpcClient.call(
        'monorail.Users', 'GetUsersProjects', {userRefs});
    dispatch({type: FETCH_PROJECTS_SUCCESS, usersProjects: resp.usersProjects});
  } catch (error) {
    dispatch({type: FETCH_PROJECTS_FAILURE, error});
  }
};

/**
 * Fetches all of a given user's hotlists.
 * @param {UserRef} userRef The user to fetch hotlists for.
 * @return {function(function): Promise<Array<HotlistV0>>}
 */
export const fetchHotlists = (userRef) => async (dispatch) => {
  dispatch({type: FETCH_HOTLISTS_START});

  try {
    const resp = await prpcClient.call(
        'monorail.Features', 'ListHotlistsByUser', {user: userRef});

    const hotlists = resp.hotlists || [];
    hotlists.sort((hotlistA, hotlistB) => {
      return hotlistA.name.localeCompare(hotlistB.name);
    });
    dispatch({type: FETCH_HOTLISTS_SUCCESS, hotlists});

    return hotlists;
  } catch (error) {
    dispatch({type: FETCH_HOTLISTS_FAILURE, error});
  };
};

/**
 * Fetches user preferences for the logged in user.
 * @return {function(function): Promise<void>}
 */
export const fetchPrefs = () => async (dispatch) => {
  dispatch({type: FETCH_PREFS_START});

  try {
    const resp = await prpcClient.call(
        'monorail.Users', 'GetUserPrefs', {});
    const prefs = {};
    (resp.prefs || []).forEach(({name, value}) => {
      prefs[name] = value;
    });
    dispatch({type: FETCH_PREFS_SUCCESS, prefs});
  } catch (error) {
    dispatch({type: FETCH_PREFS_FAILURE, error});
  };
};

/**
 * Action creator for setting a user's preferences.
 *
 * @param {Object} newPrefs
 * @param {boolean} saveChanges
 * @return {function(function): Promise<void>}
 */
export const setPrefs = (newPrefs, saveChanges = true) => async (dispatch) => {
  if (!saveChanges) {
    dispatch({type: SET_PREFS_SUCCESS, newPrefs});
    return;
  }

  dispatch({type: SET_PREFS_START});

  try {
    const message = {prefs: newPrefs};
    await prpcClient.call(
        'monorail.Users', 'SetUserPrefs', message);
    dispatch({type: SET_PREFS_SUCCESS, newPrefs});

    // Re-fetch the user's prefs after saving to prevent prefs from
    // getting out of sync.
    dispatch(fetchPrefs());
  } catch (error) {
    dispatch({type: SET_PREFS_FAILURE, error});
  }
};

/**
 * Action creator to initiate the gapi.js login flow.
 *
 * @return {Promise} Resolved only when gapi.js login succeeds.
 */
export const initGapiLogin = () => (dispatch) => {
  dispatch({type: GAPI_LOGIN_START});

  return new Promise(async (resolve) => {
    try {
      await loadGapi();
      gapi.auth2.getAuthInstance().signIn().then(async () => {
        const email = await fetchGapiEmail();
        dispatch({type: GAPI_LOGIN_SUCCESS, email: email});
        resolve();
      });
    } catch (error) {
      // TODO(jeffcarp): Pop up a message that signIn failed.
      dispatch({type: GAPI_LOGIN_FAILURE, error});
    }
  });
};

/**
 * Action creator to log the user out of gapi.js
 *
 * @return {undefined}
 */
export const initGapiLogout = () => async (dispatch) => {
  dispatch({type: GAPI_LOGOUT_START});

  try {
    await loadGapi();
    gapi.auth2.getAuthInstance().signOut().then(() => {
      dispatch({type: GAPI_LOGOUT_SUCCESS, email: ''});
    });
  } catch (error) {
    // TODO(jeffcarp): Pop up a message that signOut failed.
    dispatch({type: GAPI_LOGOUT_FAILURE, error});
  }
};
