import Immutable from 'immutable';
import * as l from '../lock/index';
import * as client from '../lock/client/index';

export function initDatabase(model, options) {
  model = model.setIn(
    ["database", "opts"],
    Immutable.fromJS(processDatabaseOptions(options))
  );

  // TODO: remove duplicate connection information
  return l.registerConnection(
    model,
    "database",
    "auth0",
    databaseConnection(model)
  );
}

function processDatabaseOptions(options) {
  let {
    activities,
    databaseConnection,
    disableResetAction,
    disableSignUpAction,
    loginAfterSignUp,
    resetLink,
    signUpLink,
    usernameStyle
   } = options;

  if (!databaseConnection || typeof databaseConnection !== "string") {
    throw new Error("The `databaseConnection` option needs to be provided.");
  }

  usernameStyle = usernameStyle === "username" ? "username" : "email";

  const availableActivities = ["login", "signUp", "resetPassword"];
  activities = activities === undefined ? availableActivities : activities;

  if (!Array.isArray(activities) || activities.length === 0) {
    throw new Error("When provided, the `activities` option array needs to contain at least one activity.");
  }

  activities = activities.filter(x => availableActivities.indexOf(x) > -1);
  if (activities.length === 0) {
    throw new Error("When provided, the `activities` option array needs to contain at least one valid activity (\"login\", \"signUp\" or \"requestPassword\").");
  }

  if (disableResetAction != undefined && typeof disableResetAction != "boolean") {
    l.warn(options, "The `disableResetAction` option will be ignored, because it is not a booelan.");
  } else if (disableResetAction) {
    activities = activities.filter(x => x != "resetPassword");
  }

  if (disableSignUpAction != undefined && typeof disableSignUpAction != "boolean") {
    l.warn(options, "The `disableSignUpAction` option will be ignored, because it is not a booelan.");
  } else if (disableSignUpAction) {
    activities = activities.filter(x => x != "signUp");
  }

  if (resetLink != undefined && typeof resetLink != "string") {
    l.warn(options, "The `resetLink` option will be ignored, because it is not a string");
    resetLink = undefined;
  }

  if (signUpLink != undefined && typeof signUpLink != "string") {
    l.warn(options, "The `signUpLink` option will be ignored, because it is not a string");
    signUpLink = undefined;
  }

  loginAfterSignUp = loginAfterSignUp === false ? false : true;

  return {
    activities,
    connection: databaseConnection,
    loginAfterSignUp,
    resetLink,
    signUpLink,
    usernameStyle
  };
}

export function databaseConnection(m) {
  return m.getIn(["database", "opts", "connection"]);
}

export function resetLink(m, notFound="") {
  return m.getIn(["database", "opts", "resetLink"], notFound);
}

export function signUpLink(m, notFound="") {
  return m.getIn(["database", "opts", "signUpLink"], notFound);
}

export function setActivity(m, name) {
  return l.clearGlobalSuccess(l.clearGlobalError(m.set("activity", name)));
}

export function getActivity(m) {
  return m.get("activity", m.getIn(["database", "opts", "activities", 0]));
}

export function authWithUsername(m) {
  return m.getIn(["database", "opts", "usernameStyle"]) === "username";
}

export function hasActivity(m, s) {
  return m.getIn(["database", "opts", "activities"]).contains(s);
}

export function shouldAutoLogin(m) {
  return m.getIn(["database", "opts", "loginAfterSignUp"]);
}

export function passwordStrengthPolicy(m) {
  return client
    .connection(m, "auth0", databaseConnection(m))
    .get("passwordPolicy", "none");
}

@@ -480,32 +480,16 @@
   let %7B%0A
-    activities,%0A
     data
@@ -500,24 +500,24 @@
 Connection,%0A
+
     disableR
@@ -873,24 +873,13 @@
 %0A%0A  
-const availableA
+let a
 ctiv
@@ -927,537 +927,8 @@
 d%22%5D;
-%0A  activities = activities === undefined ? availableActivities : activities;%0A%0A  if (!Array.isArray(activities) %7C%7C activities.length === 0) %7B%0A    throw new Error(%22When provided, the %60activities%60 option array needs to contain at least one activity.%22);%0A  %7D%0A%0A  activities = activities.filter(x =%3E availableActivities.indexOf(x) %3E -1);%0A  if (activities.length === 0) %7B%0A    throw new Error(%22When provided, the %60activities%60 option array needs to contain at least one valid activity (%5C%22login%5C%22, %5C%22signUp%5C%22 or %5C%22requestPassword%5C%22).%22);%0A  %7D
 %0A%0A  

Remove activities option