/**
 * 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.hadoop.security;

import static org.apache.hadoop.security.LdapGroupsMapping.LDAP_CTX_FACTORY_CLASS_DEFAULT;
import static org.apache.hadoop.security.LdapGroupsMapping.LDAP_CTX_FACTORY_CLASS_KEY;
import static org.apache.hadoop.security.LdapGroupsMapping.LDAP_URL_KEY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.spi.InitialContextFactory;

import org.apache.hadoop.conf.Configuration;
import org.junit.Before;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;

import java.util.Hashtable;

public class TestLdapGroupsMappingBase {
  @Mock
  private DirContext context;
  @Mock
  private NamingEnumeration<SearchResult> userNames;
  @Mock
  private NamingEnumeration<SearchResult> groupNames;
  @Mock
  private NamingEnumeration<SearchResult> parentGroupNames;
  @Mock
  private SearchResult userSearchResult;
  @Mock
  private Attributes attributes;
  @Spy
  private LdapGroupsMapping groupsMapping = new LdapGroupsMapping();

  private String[] testGroups = new String[] {"group1", "group2"};
  private String[] testParentGroups =
      new String[] {"group1", "group2", "group1_1"};

  @Before
  public void setupMocksBase() throws NamingException {
    MockitoAnnotations.initMocks(this);
    DirContext ctx = getContext();

    when(ctx.search(Mockito.anyString(), Mockito.anyString(),
        Mockito.any(Object[].class), Mockito.any(SearchControls.class))).
        thenReturn(userNames);
    // We only ever call hasMoreElements once for the user NamingEnum, so
    // we can just have one return value
    when(userNames.hasMoreElements()).thenReturn(true);

    SearchResult groupSearchResult = mock(SearchResult.class);
    // We're going to have to define the loop here. We want two iterations,
    // to get both the groups
    when(groupNames.hasMoreElements()).thenReturn(true, true, false);
    when(groupNames.nextElement()).thenReturn(groupSearchResult);

    // Define the attribute for the name of the first group
    Attribute group1Attr = new BasicAttribute("cn");
    group1Attr.add(testGroups[0]);
    Attributes group1Attrs = new BasicAttributes();
    group1Attrs.put(group1Attr);

    // Define the attribute for the name of the second group
    Attribute group2Attr = new BasicAttribute("cn");
    group2Attr.add(testGroups[1]);
    Attributes group2Attrs = new BasicAttributes();
    group2Attrs.put(group2Attr);

    // This search result gets reused, so return group1, then group2
    when(groupSearchResult.getAttributes()).
        thenReturn(group1Attrs, group2Attrs);

    when(getUserNames().nextElement()).
        thenReturn(getUserSearchResult());

    when(getUserSearchResult().getAttributes()).thenReturn(getAttributes());
    // Define results for groups 1 level up
    SearchResult parentGroupResult = mock(SearchResult.class);

    // only one parent group
    when(parentGroupNames.hasMoreElements()).thenReturn(true, false);
    when(parentGroupNames.nextElement()).
        thenReturn(parentGroupResult);

    // Define the attribute for the parent group
    Attribute parentGroup1Attr = new BasicAttribute("cn");
    parentGroup1Attr.add(testParentGroups[2]);
    Attributes parentGroup1Attrs = new BasicAttributes();
    parentGroup1Attrs.put(parentGroup1Attr);

    // attach the attributes to the result
    when(parentGroupResult.getAttributes()).thenReturn(parentGroup1Attrs);
    when(parentGroupResult.getNameInNamespace()).
        thenReturn("CN=some_group,DC=test,DC=com");
  }

  protected Configuration getBaseConf() {
    return getBaseConf("ldap://test");
  }

  protected Configuration getBaseConf(String ldapUrl) {
    return getBaseConf(ldapUrl, getContext());
  }

  protected Configuration getBaseConf(
      String ldapUrl, DirContext contextToReturn) {
    DummyLdapCtxFactory.setContextToReturn(contextToReturn);
    DummyLdapCtxFactory.setExpectedLdapUrl(ldapUrl);

    Configuration conf = new Configuration();
    conf.set(LDAP_URL_KEY, ldapUrl);
    conf.setClass(LDAP_CTX_FACTORY_CLASS_KEY, DummyLdapCtxFactory.class,
        InitialContextFactory.class);
    return conf;
  }

  protected DirContext getContext() {
    return context;
  }

  protected NamingEnumeration<SearchResult> getUserNames() {
    return userNames;
  }

  protected NamingEnumeration<SearchResult> getGroupNames() {
    return groupNames;
  }

  protected SearchResult getUserSearchResult() {
    return userSearchResult;
  }

  protected Attributes getAttributes() {
    return attributes;
  }

  protected LdapGroupsMapping getGroupsMapping() {
    return groupsMapping;
  }

  protected String[] getTestGroups() {
    return testGroups;
  }

  protected NamingEnumeration getParentGroupNames() {
    return parentGroupNames;
  }

  protected String[] getTestParentGroups() {
    return testParentGroups;
  }

  /**
   * Ldap Context Factory implementation to be used for testing to check
   * contexts are requested for the expected LDAP server URLs etc.
   */
  public static class DummyLdapCtxFactory implements InitialContextFactory {

    private static DirContext contextToReturn;
    private static String expectedLdapUrl;

    public DummyLdapCtxFactory() {
    }

    protected static void setContextToReturn(DirContext ctx) {
      contextToReturn = ctx;
    }

    protected static void setExpectedLdapUrl(String url) {
      expectedLdapUrl = url;
    }

    @Override
    public Context getInitialContext(Hashtable<?, ?> env)
        throws NamingException {
      if (expectedLdapUrl != null) {
        String actualLdapUrl = (String) env.get(Context.PROVIDER_URL);
        assertEquals(expectedLdapUrl, actualLdapUrl);
      }
      if (contextToReturn == null) {
        InitialContextFactory defaultFactory = null;
        try {
          defaultFactory = LDAP_CTX_FACTORY_CLASS_DEFAULT.newInstance();
        } catch (ReflectiveOperationException e) {
          fail("Could not initialize the default factory");
        }
        return defaultFactory.getInitialContext(env);
      }
      return contextToReturn;
    }
  }
}
