// 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 qs from 'qs';


/**
 * With lists a and b, get the elements that are in a but not in b.
 * result = a - b
 * @param {Array} listA
 * @param {Array} listB
 * @param {function?} equals
 * @return {Array}
 */
export function arrayDifference(listA, listB, equals = undefined) {
  if (!equals) {
    equals = (a, b) => (a === b);
  }
  listA = listA || [];
  listB = listB || [];
  return listA.filter((a) => {
    return !listB.find((b) => (equals(a, b)));
  });
}

/**
 * Check to see if a Set contains any of a list of values.
 *
 * @param {Set} set the Set to check for values in.
 * @param {Iterable} values checks if any of these values are included.
 * @return {boolean} whether the Set has any of the values or not.
 */
export function setHasAny(set, values) {
  for (const value of values) {
    if (set.has(value)) {
      return true;
    }
  }
  return false;
}

/**
 * Capitalize the first letter of a given string.
 * @param {string} str
 * @return {string}
 */
export function capitalizeFirst(str) {
  return `${str.charAt(0).toUpperCase()}${str.substring(1)}`;
}

/**
 * Check if a string has a prefix, ignoring case.
 * @param {string} str
 * @param {string} prefix
 * @return {boolean}
 */
export function hasPrefix(str, prefix) {
  return str.toLowerCase().startsWith(prefix.toLowerCase());
}

/**
 * Returns a string without specified prefix
 * @param {string} str
 * @param {string} prefix
 * @return {string}
 */
export function removePrefix(str, prefix) {
  return str.substr(prefix.length);
}

// TODO(zhangtiff): Make this more grammatically correct for
// more than two items.
export function arrayToEnglish(arr) {
  if (!arr) return '';
  return arr.join(' and ');
}

export function pluralize(count, singular, pluralArg) {
  const plural = pluralArg || singular + 's';
  return count === 1 ? singular : plural;
}

export function objectToMap(obj = {}) {
  const map = new Map();
  Object.keys(obj).forEach((key) => {
    map.set(key, obj[key]);
  });
  return map;
}

/**
 * Given an Object, extract a list of values from it, based on some
 * specified keys.
 *
 * @param {Object} obj the Object to read values from.
 * @param {Array} keys the Object keys to fetch values for.
 * @return {Array} Object values matching the given keys.
 */
export function objectValuesForKeys(obj, keys = []) {
  return keys.map((key) => ((key in obj) ? obj[key] : undefined));
}

/**
 * Checks to see if object has no keys
 * @param {Object} obj
 * @return {boolean}
 */
export function isEmptyObject(obj) {
  return Object.keys(obj).length === 0;
}

/**
 * Checks if two strings are equal, case-insensitive
 * @param {string} a
 * @param {string} b
 * @return {boolean}
 */
export function equalsIgnoreCase(a, b) {
  if (a == b) return true;
  if (!a || !b) return false;
  return a.toLowerCase() === b.toLowerCase();
}

export function immutableSplice(arr, index, count, ...addedItems) {
  if (!arr) return '';

  return [...arr.slice(0, index), ...addedItems, ...arr.slice(index + count)];
}

/**
 * Computes a new URL for a page based on an exiting path and set of query
 * params.
 *
 * @param {string} baseUrl the base URL without query params.
 * @param {Object} oldParams original query params before changes.
 * @param {Object} newParams query parameters to override existing ones.
 * @param {Array} deletedParams list of keys to be cleared.
 * @return {string} the new URL with the updated params.
 */
export function urlWithNewParams(baseUrl = '',
    oldParams = {}, newParams = {}, deletedParams = []) {
  const params = {...oldParams, ...newParams};
  deletedParams.forEach((name) => {
    delete params[name];
  });

  const queryString = qs.stringify(params);

  return `${baseUrl}${queryString ? '?' : ''}${queryString}`;
}

/**
 * Finds out whether a user is a member of a given project based on
 * project membership info.
 *
 * @param {Object} userRef reference to a given user. Expects an id.
 * @param {string} projectName name of the project being searched for.
 * @param {Map} usersProjects all known user project memberships where
 *  keys are userId and values are Objects with expected values
 *  for {ownerOf, memberOf, contributorTo}.
 * @return {boolean} whether the user is a member of the project or not.
 */
export function userIsMember(userRef, projectName, usersProjects = new Map()) {
  // TODO(crbug.com/monorail/5968): Find a better place to place this function
  if (!userRef || !userRef.userId || !projectName) return false;
  const userProjects = usersProjects.get(userRef.userId);
  if (!userProjects) return false;
  const {ownerOf = [], memberOf = [], contributorTo = []} = userProjects;
  return ownerOf.includes(projectName) ||
    memberOf.includes(projectName) ||
    contributorTo.includes(projectName);
}

/**
 * Creates a function that checks two objects are not equal
 * based on a set of property keys
 *
 * @param {Set<string>} props
 * @return {function(): boolean}
 */
export function createObjectComparisonFunc(props) {
  /**
   * Computes whether set of properties have changed
   * @param {Object<string, string>} newVal
   * @param {Object<string, string>} oldVal
   * @return {boolean}
   */
  return function(newVal, oldVal) {
    if (oldVal === undefined && newVal === undefined) {
      return false;
    } else if (oldVal === undefined || newVal === undefined) {
      return true;
    } else if (oldVal === null && newVal === null) {
      return false;
    } else if (oldVal === null || newVal === null) {
      return true;
    }

    return Array.from(props)
        .some((propName) => newVal[propName] !== oldVal[propName]);
  };
}

/**
 * Calculates whether to wait for memberDefaultQuery to exist prior
 * to fetching IssueList. Logged in users may use a default query.
 * @param {Object} queryParams
 * @return {boolean}
 */
export const shouldWaitForDefaultQuery = (queryParams) => {
  return !queryParams.hasOwnProperty('q');
};

// constant value for required redirect project
const redirectProjects = Object.freeze(['pigweed', 'git', 'gerrit', 'skia', 'fuchsia']);

/**
 * Generate the url link for issue in project.
 * @param {string} projectName Name of the project.
 * @param {string} subUrl the sub URL without query params.
 * @param {Object} params the query params.
 * @return {string} the new URL
 */
export function generateProjectIssueURL(projectName, subPath, params = {}) {
  const queryString = window.location.search;
  const urlParams = new URLSearchParams(queryString);
  const noRedirect = urlParams.has('no_tracker_redirect');
  let baseUrl = '';
  if (!noRedirect && redirectProjects.includes(projectName)) {
    // Full url path will trigger backend service call to handle redirect.
    baseUrl = 'https://bugs.chromium.org/p/' + projectName + '/issues' + subPath;
    return urlWithNewParams(baseUrl, params, {}, undefined)
  } else {
    baseUrl = '/p/' + projectName + '/issues' + subPath;
    const noRedirectParam = noRedirect ? {'no_tracker_redirect' : 1} : undefined
    return urlWithNewParams(baseUrl, params, noRedirectParam, undefined)
  }
}