/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package javax.jdo;

import static javax.jdo.Constants.PROPERTY_ENHANCER_VENDOR_NAME;
import static javax.jdo.Constants.PROPERTY_ENHANCER_VERSION_NUMBER;

import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.jdo.metadata.JDOMetadata;

/**
 * Tests class javax.jdo.Enhancer (main class).
 *
 * <p>
 */
public class MockEnhancer implements JDOEnhancer {

  static final Properties props = new Properties();

  static {
    props.put(PROPERTY_ENHANCER_VENDOR_NAME, "Mock Enhancer");
    props.put(PROPERTY_ENHANCER_VERSION_NUMBER, "2.3.0");
    props.put("MockKey", "MockValue");
  }

  @SuppressWarnings("unused")
  private boolean verbose;

  private int numberOfElements;
  private final List<String> classNames = new ArrayList<>();
  private final List<String> jarNames = new ArrayList<>();
  private final List<String> jdoNames = new ArrayList<>();
  private final List<String> puNames = new ArrayList<>();

  @SuppressWarnings("unused")
  private String outputDirectory = null;

  public MockEnhancer() {}

  public Properties getProperties() {
    return props;
  }

  public JDOEnhancer setVerbose(boolean flag) {
    this.verbose = flag;
    return this;
  }

  public JDOEnhancer setOutputDirectory(String dirName) {
    outputDirectory = dirName;
    return this;
  }

  public JDOEnhancer setClassLoader(ClassLoader loader) {
    // check to see if JDOHelper is loadable from the loader
    try {
      loader.loadClass("javax.jdo.JDOHelper");
    } catch (ClassNotFoundException ex) {
      // bad
      throw new JDOFatalInternalException("Should be able to load JDOHelper from the class loader");
    }
    return this;
  }

  public JDOEnhancer addPersistenceUnit(String persistenceUnit) {
    numberOfElements++;
    this.puNames.add(persistenceUnit);
    return this;
  }

  public JDOEnhancer addClass(String className, byte[] bytes) {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  public JDOEnhancer addClasses(String... classNames) {
    numberOfElements += classNames.length;
    this.classNames.addAll(Arrays.asList(classNames));
    return this;
  }

  public JDOEnhancer addFiles(String... metadataFiles) {
    numberOfElements += metadataFiles.length;
    this.jdoNames.addAll(Arrays.asList(metadataFiles));
    return this;
  }

  public JDOEnhancer addJar(String jarFileName) {
    numberOfElements++;
    this.jarNames.add(jarFileName);
    return this;
  }

  public int enhance() {
    return numberOfElements;
  }

  public int validate() {
    return numberOfElements;
  }

  public byte[] getEnhancedBytes(String className) {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  public void registerMetadata(JDOMetadata metadata) {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  public JDOMetadata newMetadata() {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  public byte[] transform(
      ClassLoader loader,
      String className,
      Class<?> classBeingRedefined,
      ProtectionDomain protectionDomain,
      byte[] classfileBuffer)
      throws IllegalClassFormatException {
    throw new UnsupportedOperationException("Not supported yet.");
  }
}
