// Copyright 2008 Google Inc.
//
// Licensed 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 com.google.enterprise.secmgr.config;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

/**
 * A base class for implementing a configuration encode/decode class.
 */
public abstract class ConfigCodec {

  /**
   * Decode a configuration from a string.
   *
   * @param string The string to decode.
   * @return A configuration.
   * @throws IOException if there are errors while reading the configuration.
   * @throws ConfigException if the configuration is malformed.
   */
  public SecurityManagerConfig readConfig(String string)
      throws IOException, ConfigException {
    return readConfig(new StringReader(string));
  }

  /**
   * Encode a configuration as a string.
   *
   * @param config The configuration to be encoded.
   * @return The encoded string.
   * @throws IOException if there are errors while writing the configuration.
   */
  public String configToString(SecurityManagerConfig config) throws IOException {
    Writer writer = new StringWriter();
    writeConfig(config, writer);
    return writer.toString();
  }

  /**
   * Read and decode a configuration from a given source.
   *
   * @param reader The source to read the encoded configuration from.
   * @return A configuration.
   * @throws IOException if there are errors while reading the configuration.
   * @throws ConfigException if the configuration is malformed.
   */
  public SecurityManagerConfig readConfig(Reader reader)
      throws IOException, ConfigException {
    SecurityManagerConfig config = readConfigInternal(reader);
    guaranteeValidConfig(config);
    return config;
  }

  /**
   * Read and decode a configuration from a given file.
   *
   * @param file The file to read the encoded configuration from.
   * @return A configuration.
   * @throws IOException if there are errors while reading the configuration.
   * @throws ConfigException if the configuration is malformed.
   */
  public SecurityManagerConfig readConfig(File file)
      throws IOException, ConfigException {
    Reader reader = new FileReader(file);
    try {
      return readConfig(reader);
    } finally {
      reader.close();
    }
  }

  protected abstract SecurityManagerConfig readConfigInternal(Reader reader)
      throws IOException, ConfigException;

  /**
   * Encode and write a configuration to a given sink.
   *
   * @param config The configuration to be encoded.
   * @param writer The sink to write the encoded configuration to.
   * @throws IOException if there are errors while writing the configuration.
   */
  public void writeConfig(SecurityManagerConfig config, Writer writer) throws IOException {
    guaranteeValidConfig(config);
    writeConfigInternal(config, writer);
  }

  protected abstract void writeConfigInternal(SecurityManagerConfig config, Writer writer)
      throws IOException;

  private void guaranteeValidConfig(SecurityManagerConfig config) {
    if (!isValidConfig(config)) {
      throw new IllegalStateException("Config is not valid: " + config);
    }
  }

  /**
   * A valid config must contain a "default" group and that group must require a
   * username, be non-optional, and non-empty.  This in turn ensures that a saml
   * assertion from the security manager will always contain a username which
   * can in turn be used when creating policy ACLs.
   *
   * TODO(martincochran): ensure that EFE gets the right username and/or that
   * the correct saml subject is generated by the security manager.
   */
  private boolean isValidConfig(SecurityManagerConfig config) {

    return true;
    /* TODO(kstillson): I'm disabling this check.  It was added to address
     * to address the concern that PVI assignment may not be stable- specifically,
     * user1 has a forms auth cookie before any interaction with the GSA, if the
     * default CG does not insist on requires-username, then CG will be satisfied
     * but no username is set, so the PVI could come from somewhere else (e.g.
     * kerberos).  However, user2 has no cookie, so they get a ULF, and the PVI
     * is set by their forms login.  That is a problem, however, this solution
     * is too drastic, and eliminates numerous valid use-cases (such as a sec-mgr
     * that does nothing but a single forms-auth CG that doesn't need a username).
     * So We're going to have to find a more subtle solution to the original
     * problem.

    if (config.isEmpty()) {
      return true;
    }
    boolean defaultGroupEmpty = false;
    boolean someGroupNonEmpty = false;

    for (CredentialsGroup group : config) {
      if ("default".equalsIgnoreCase(group.getName())) {
        if (!group.getRequiresUsername()) {
          return false;
        }
        if (group.getIsOptional()) {
          return false;
        }
        if (!group.getElements().isEmpty()) {
          return true;
        }
      }
      if (!group.getElements().isEmpty()) {
        someGroupNonEmpty = true;
      }
    }
    return !someGroupNonEmpty;
    */
  }
}
