// Path: src/main/java/com/lmax/tool/disruptor/Resetable.java
// public interface Resetable
// {
//     /**
//      * Reset this component
//      */
//     void reset();
// }


import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.makeClass;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.makePublicFinal;
import com.lmax.tool.disruptor.Resetable;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtNewConstructor;
import java.util.HashMap;
import java.util.Map;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.addInterface;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.createField;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.createMethod;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.getUniqueIdentifier;
/*
 * Copyright 2015-2016 LMAX Ltd.
 *
 *    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.lmax.tool.disruptor.bytecode;





final class ArgumentHolderGenerator
{
    private final ArgumentHolderHelper helper = new ArgumentHolderHelper();
    private final ClassPool classPool;

    private String generatedClassName;
    private Class<?> generatedClass;
    private Map<Class<?>, Integer> parameterTypeCounts;
    private Map<Class<?>, Character> parameterFieldSuffix = new HashMap<Class<?>, Character>();

    public ArgumentHolderGenerator(final ClassPool classPool)
    {
        this.classPool = classPool;
    }

    public void createArgumentHolderClass(final Class<?> proxyInterface)
    {
        final CtClass ctClass = makeClass(classPool, "_argumentHolder_" + proxyInterface.getSimpleName() + "_" + getUniqueIdentifier());

        parameterTypeCounts = helper.getParameterTypeCounts(proxyInterface);
        createFields(ctClass);
        createMethod(ctClass, generateResetMethod());
// Path: src/main/java/com/lmax/tool/disruptor/Resetable.java
// public interface Resetable
// {
//     /**
//      * Reset this component
//      */
//     void reset();
// }


// Path: src/main/java/com/lmax/tool/disruptor/bytecode/ArgumentHolderGenerator.java
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.makeClass;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.makePublicFinal;
import com.lmax.tool.disruptor.Resetable;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtNewConstructor;
import java.util.HashMap;
import java.util.Map;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.addInterface;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.createField;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.createMethod;
import static com.lmax.tool.disruptor.bytecode.ByteCodeHelper.getUniqueIdentifier;

/*
 * Copyright 2015-2016 LMAX Ltd.
 *
 *    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.lmax.tool.disruptor.bytecode;





final class ArgumentHolderGenerator
{
    private final ArgumentHolderHelper helper = new ArgumentHolderHelper();
    private final ClassPool classPool;

    private String generatedClassName;
    private Class<?> generatedClass;
    private Map<Class<?>, Integer> parameterTypeCounts;
    private Map<Class<?>, Character> parameterFieldSuffix = new HashMap<Class<?>, Character>();

    public ArgumentHolderGenerator(final ClassPool classPool)
    {
        this.classPool = classPool;
    }

    public void createArgumentHolderClass(final Class<?> proxyInterface)
    {
        final CtClass ctClass = makeClass(classPool, "_argumentHolder_" + proxyInterface.getSimpleName() + "_" + getUniqueIdentifier());

        parameterTypeCounts = helper.getParameterTypeCounts(proxyInterface);
        createFields(ctClass);
        createMethod(ctClass, generateResetMethod());
        addInterface(ctClass, Resetable.class, classPool);