/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.oodt.security.sso;

//JDK imports
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.logging.Logger;
import javax.servlet.http.Cookie;

//APACHE imports
import org.apache.commons.codec.binary.Base64;

//LMMP imports
import org.apache.oodt.security.sso.opensso.SSOMetKeys;
import org.apache.oodt.security.sso.opensso.SSOProxy;
import org.apache.oodt.security.sso.opensso.UserDetails;

/**
 * 
 * Connects to OpenSSO's authorization endpoint and authenticates a user,
 * implementing the CAS {@link AbstractWebBasedSingleSignOn} interface. This
 * class can be used in e.g., CAS curator to link into Open SSO.
 */
public class OpenSSOImpl extends AbstractWebBasedSingleSignOn implements
    SSOMetKeys {

  private static final Logger LOG = Logger.getLogger(OpenSSOImpl.class
      .getName());

  private SSOProxy ssoProxy;

  /**
   * Default constructor.
   */
  public OpenSSOImpl() {
    this.ssoProxy = new SSOProxy();
  }

  public String getCurrentUsername() {
    String cookieVal = this.getCookieVal(USER_COOKIE_KEY);
    if (cookieVal == null) {
      // let's try and get the SSO token
      // and pull the username from there
      String ssoToken = this.getSSOToken();
      if (ssoToken != null) {
        UserDetails details = null;
        try {
          details = this.ssoProxy.getUserAttributes(ssoToken);
        } catch (Exception e) {
          e.printStackTrace();
          return UNKNOWN_USER;
        }
        return details.getAttributes().getMetadata(UID_ATTRIBUTE_NAME) != null ? details
            .getAttributes().getMetadata(UID_ATTRIBUTE_NAME) : UNKNOWN_USER;
      } else
        return UNKNOWN_USER;
    } else {
      return new String(Base64.decodeBase64(cookieVal.getBytes()));
    }
  }

  public boolean getLastConnectionStatus() {
    return this.isLoggedIn();
  }

  public boolean isLoggedIn() {
    // TODO: make sure the token is valid?
    return (this.getSSOToken() == null) ? false : true;
  }

  public boolean login(String username, String password) {

    String ssoToken = null;
    try {
      ssoToken = this.ssoProxy.authenticate(username, password);
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }

    this.addCookie(SSO_COOKIE_KEY, "\"" + new String(ssoToken) + "\"");

    this.addCookie(USER_COOKIE_KEY,
        "\"" + new String(Base64.encodeBase64(username.getBytes())) + "\"");

    return true;
  }

  public void logout() {
    this.ssoProxy.logout(this.getSSOToken());
    this.clearCookie(SSO_COOKIE_KEY);
    this.clearCookie(USER_COOKIE_KEY);
  }

  /**
   * Gets the SSO groups for the LMMP user, identified by her
   * <code>ssoAuth</code>, where her User ID is provided by
   * {@link OpenSSOImpl#getCurrentUsername()} and her Token is provided by
   * {@link OpenSSOImpl#getSSOToken()}.
   * 
   * @return A {@link List} of String LMMP groups for the User.
   * @throws Exception
   *           If any error (e.g., HTTP REST error) occurs.
   */
  public List<String> getGroupsForUser() throws Exception {
    String token = this.getSSOToken();
    if (token == null) {
      return Collections.EMPTY_LIST;
    } else {
      UserDetails details = this.ssoProxy.getUserAttributes(token);
      // groups are formatted in this response to include whole
      // principals, like lmmp-infra,...principal
      // so split on "," and take the first token to get the group name
      List<String> groups = new Vector<String>();
      for (String rawGroup : details.getRoles()) {
        groups.add(rawGroup.split(",")[0]);
      }

      return groups;
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.apache.oodt.security.sso.SingleSignOn#retrieveGroupsForUser(java.lang
   * .String)
   */
  @Override
  public List<String> retrieveGroupsForUser(String username) {
    // FIXME: not implemented yet
    return Collections.EMPTY_LIST;
  }

  protected String getSSOToken() {
    String cookieVal = this.getCookieVal(SSO_COOKIE_KEY);
    if (cookieVal != null) {
      return new String(cookieVal);
    } else
      return null;
  }

  private String getCookieVal(String name) {
    Cookie[] cookies = this.req.getCookies();
    for (Cookie cookie : cookies) {
      if (cookie.getName().equals(name)) {
        String cookieVal = cookie.getValue().startsWith("\"")
            && cookie.getValue().endsWith("\"") ? cookie.getValue().substring(
            1, cookie.getValue().length() - 1) : cookie.getValue();
        return cookieVal;
      }
    }

    return null;
  }

  private void addCookie(String name, String val) {
    Cookie userCookie = new Cookie(name, val);
    userCookie.setPath("/");
    userCookie.setMaxAge((int) (System.currentTimeMillis() + (60 * 15)));
    this.res.addCookie(userCookie);
  }

  private void clearCookie(String name) {
    Cookie userCookie = new Cookie(name, "blank");
    userCookie.setPath("/");
    userCookie.setMaxAge(0);
    this.res.addCookie(userCookie);
  }

}
