// 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 {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});
  }
};
