// 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 {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 {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: 'true',
        ...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});
  }
};
