/**
   * Interface: GET /yes-api/rest/auth/check
   *
   * <p>
   *
   * <p>Check interface that allows to check authentication state of user. The token for the
   * authenticated cart is returned back as response header and also as a cookie.
   *
   * <p>
   *
   * <p>
   *
   * <h3>Headers for operation</h3>
   *
   * <p>
   *
   * <table border="1">
   *     <tr><td>Accept</td><td>application/json or application/xml</td></tr>
   *     <tr><td>yc</td><td>token uuid</td></tr>
   * </table>
   *
   * <p>
   *
   * <p>
   *
   * <h3>Parameters for operation</h3>
   *
   * <p>NONE
   *
   * <p>
   *
   * <p>
   *
   * <h3>Output</h3>
   *
   * <p>
   *
   * <table border="1">
   *     <tr><td>JSON example</td><td>
   * <pre><code>
   * {
   *    "success" : true,
   *    "greeting" : "Bob Doe",
   *    "token" : {
   *        "uuid" : "1db8def2-21e0-44d2-aeb0-56baae761129"
   *    },
   *    "error" : null
   * }
   * </code></pre>
   *     </td></tr>
   *     <tr><td>XML example</td><td>
   * <pre><code>
   * &lt;authentication-result&gt;
   *    &lt;greeting&gt;Bob Doe&lt;/greeting&gt;
   *    &lt;success&gt;true&lt;/success&gt;
   *    &lt;token&gt;
   *       &lt;uuid&gt;1db8def2-21e0-44d2-aeb0-56baae761129&lt;/uuid&gt;
   *    &lt;/token&gt;
   * &lt;/authentication-result&gt;
   * </code></pre>
   *     </td></tr>
   * </table>
   *
   * <p>
   *
   * <p>
   *
   * <h3>Error codes</h3>
   *
   * <p>
   *
   * <table border="1">
   *     <tr><td>SESSION_EXPIRED</td><td>user session expired</td></tr>
   *     <tr><td>INACTIVE_FOR_SHOP</td><td>user is inactive for shop</td></tr>
   *     <tr><td>AUTH_FAILED</td><td>user exists but credentials are not valid</td></tr>
   * </table>
   *
   * @param request request
   * @param response response
   * @return authentication result
   */
  @RequestMapping(
      value = "/check",
      method = RequestMethod.GET,
      produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
  public @ResponseBody AuthenticationResultRO check(
      final HttpServletRequest request, final HttpServletResponse response) {

    final ShoppingCart cart = cartMixin.getCurrentCart();
    cartMixin.persistShoppingCart(request, response);

    switch (cart.getLogonState()) {
      case ShoppingCart.LOGGED_IN:
        return new AuthenticationResultRO(cart.getCustomerName(), new TokenRO(cart.getGuid()));
      case ShoppingCart.SESSION_EXPIRED:
        final AuthenticationResultRO authExpired =
            new AuthenticationResultRO(cart.getCustomerName(), new TokenRO(cart.getGuid()));
        authExpired.setAuthenticated(false);
        authExpired.setCode("SESSION_EXPIRED");
        return authExpired;
      case ShoppingCart.INACTIVE_FOR_SHOP:
        final AuthenticationResultRO authInactive =
            new AuthenticationResultRO(cart.getCustomerName(), new TokenRO(cart.getGuid()));
        authInactive.setAuthenticated(false);
        authInactive.setCode("INACTIVE_FOR_SHOP");
        return authInactive;
      case ShoppingCart.NOT_LOGGED:
      default:
        return new AuthenticationResultRO("AUTH_FAILED");
    }
  }
  /**
   * Interface: PUT /yes-api/rest/auth/login
   *
   * <p>
   *
   * <p>Login interface that allows to authenticate user cart. The token for the authenticated cart
   * is returned back as response header and also as a cookie.
   *
   * <p>
   *
   * <p>
   *
   * <h3>Headers for operation</h3>
   *
   * <p>
   *
   * <table border="1">
   *     <tr><td>Content-Type</td><td>application/json or application/xml</td></tr>
   *     <tr><td>Accept</td><td>application/json or application/xml</td></tr>
   *     <tr><td>yc</td><td>token uuid (optional)</td></tr>
   * </table>
   *
   * <p>
   *
   * <p>
   *
   * <h3>Parameters for login PUT operation</h3>
   *
   * <p>
   *
   * <table border="1">
   *     <tr><td>JSON example</td><td>
   * <pre><code>
   * {
   *    "username": "******",
   *    "password": "******",
   *    "activate": true
   * }
   * </code></pre>
   *     </td></tr>
   *     <tr><td>XML example</td><td>
   * <pre><code>
   * &lt;login&gt;
   *    &lt;username&gt;[email protected]&lt;/username&gt;
   *    &lt;password&gt;bBuyM-6-&lt;/password&gt;
   *    &lt;activate&gt;true&lt;/activate&gt;
   * &lt;/login&gt;
   * </code></pre>
   *     </td></tr>
   * </table>
   *
   * <p>
   *
   * <p>
   *
   * <h3>Output</h3>
   *
   * <p>
   *
   * <table border="1">
   *     <tr><td>JSON example</td><td>
   * <pre><code>
   * {
   *    "success" : true,
   *    "greeting" : "Bob Doe",
   *    "token" : {
   *        "uuid" : "1db8def2-21e0-44d2-aeb0-56baae761129"
   *    },
   *    "error" : null
   * }
   * </code></pre>
   *     </td></tr>
   *     <tr><td>XML example</td><td>
   * <pre><code>
   * &lt;authentication-result&gt;
   *    &lt;greeting&gt;Bob Doe&lt;/greeting&gt;
   *    &lt;success&gt;true&lt;/success&gt;
   *    &lt;token&gt;
   *       &lt;uuid&gt;1db8def2-21e0-44d2-aeb0-56baae761129&lt;/uuid&gt;
   *    &lt;/token&gt;
   * &lt;/authentication-result&gt;
   * </code></pre>
   *     </td></tr>
   * </table>
   *
   * <p>
   *
   * <p>
   *
   * <h3>Error codes</h3>
   *
   * <p>
   *
   * <table border="1">
   *     <tr><td>USER_FAILED</td><td>user does not exist</td></tr>
   *     <tr><td>AUTH_FAILED</td><td>user exists but credentials are not valid</td></tr>
   *     <tr><td>INACTIVE_FOR_SHOP</td><td>user exists but profile is active for given shop, use activate=true to force activation on login</td></tr>
   * </table>
   *
   * @param loginRO login parameters (see examples above)
   * @param request request
   * @param response response
   * @return authentication result
   */
  @RequestMapping(
      value = "/login",
      method = RequestMethod.PUT,
      produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
  public @ResponseBody AuthenticationResultRO login(
      final @RequestBody LoginRO loginRO,
      final HttpServletRequest request,
      final HttpServletResponse response) {

    final Customer customer = customerServiceFacade.getCustomerByEmail(loginRO.getUsername());

    if (customer != null) {

      do {

        executeLoginCommand(loginRO.getUsername(), loginRO.getPassword());

        final TokenRO token = cartMixin.persistShoppingCart(request, response);

        ShoppingCart cart = cartMixin.getCurrentCart();
        final int logOnState = cart.getLogonState();
        if (logOnState == ShoppingCart.LOGGED_IN) {

          return new AuthenticationResultRO(cart.getCustomerName(), token);

        } else if (logOnState == ShoppingCart.INACTIVE_FOR_SHOP) {

          if (loginRO.isActivate()) {
            // Login again with inactive state adds customer to shop
            continue;
          }

          return new AuthenticationResultRO("INACTIVE_FOR_SHOP");

        } else {

          // any other state should break to AUTH_FAILED
          break;
        }

      } while (true);

      return new AuthenticationResultRO("AUTH_FAILED");
    }

    return new AuthenticationResultRO("USER_FAILED");
  }