/*
 * Copyright 2016 Davide Maestroni
 *
 * 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.
 */

// GENERATED CODE - PLEASE DO NOT EDIT

${generatedPackage}

public final class ${generatedClassName}${genericTypes} implements ${interfaceFullName} {

    private final com.github.dm.jrt.android.v4.core.LoaderContextCompat mContext;

    public ${generatedClassName}(@org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.v4.core.LoaderContextCompat context,
            @org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.object.ContextInvocationTarget<?> target,
            @org.jetbrains.annotations.NotNull final com.github.dm.jrt.core.config.InvocationConfiguration invocationConfiguration,
            @org.jetbrains.annotations.NotNull final com.github.dm.jrt.object.config.ObjectConfiguration objectConfiguration,
            @org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.core.config.LoaderConfiguration loaderConfiguration) {
        com.github.dm.jrt.core.util.ConstantConditions.notNull("Loader context", context);
        com.github.dm.jrt.core.util.ConstantConditions.notNull("invocation configuration", invocationConfiguration);
        com.github.dm.jrt.core.util.ConstantConditions.notNull("object configuration", objectConfiguration);
        com.github.dm.jrt.core.util.ConstantConditions.notNull("Loader configuration", loaderConfiguration);
        if (!target.isOfType(${classErasure}.class)) {
            throw new IllegalArgumentException("the invocation target must be the class or an instance of " +
                    "${classFullName}");
        }

        mContext = context;
        ${routineFieldsInit}
    }

    @org.jetbrains.annotations.NotNull
    public static ContextBuilder on(@org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.v4.core.LoaderContextCompat context) {
        return new ContextBuilder(context);
    }

    @org.jetbrains.annotations.NotNull
    private static <OUT> com.github.dm.jrt.android.core.builder.LoaderRoutineBuilder<Object, OUT> getBuilder(
            @org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.v4.core.LoaderContextCompat context,
            @org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.core.invocation.ContextInvocationFactory<Object, OUT> factory) {
        return com.github.dm.jrt.android.v4.core.JRoutineLoaderCompat.on(context).with(factory);
    }

    public static class ContextBuilder {

        private final com.github.dm.jrt.android.v4.core.LoaderContextCompat mContext;

        private ContextBuilder(@org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.v4.core.LoaderContextCompat context) {
            mContext = com.github.dm.jrt.core.util.ConstantConditions.notNull("Loader context", context);
        }

        @org.jetbrains.annotations.NotNull
        public ${genericTypes} com.github.dm.jrt.android.proxy.builder.LoaderProxyObjectBuilder<${interfaceFullName}> with(@org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.object.ContextInvocationTarget<? extends ${classFullName}> target) {
            if (!target.isOfType(${classErasure}.class)) {
                throw new IllegalArgumentException("the invocation target must be the class or an instance of " +
                        "${classFullName}");
            }

            return new LoaderProxyObjectBuilder${genericTypes}(mContext, target);
        }
    }

    private static class LoaderProxyObjectBuilder${genericTypes} extends com.github.dm.jrt.android.proxy.builder.AbstractLoaderProxyObjectBuilder<${interfaceFullName}> {

        private final com.github.dm.jrt.android.v4.core.LoaderContextCompat mContext;

        private final com.github.dm.jrt.android.object.ContextInvocationTarget<?> mTarget;

        private LoaderProxyObjectBuilder(@org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.v4.core.LoaderContextCompat context,
                @org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.object.ContextInvocationTarget<?> target) {
            mContext = com.github.dm.jrt.core.util.ConstantConditions.notNull("Loader context", context);
            mTarget = com.github.dm.jrt.core.util.ConstantConditions.notNull("invocation target", target);
        }

        @Override
        @org.jetbrains.annotations.NotNull
        protected Class<? super ${interfaceFullName}> getInterfaceClass() {
            return ${interfaceErasure}.class;
        }

        @Override
        @org.jetbrains.annotations.Nullable
        protected Object getInvocationContext() {
            return mContext.getComponent();
        }

        @Override
        @org.jetbrains.annotations.NotNull
        protected Class<?> getTargetClass() {
            return mTarget.getTargetClass();
        }

        @Override
        @org.jetbrains.annotations.NotNull
        protected ${interfaceFullName} newProxy(
                @org.jetbrains.annotations.NotNull final com.github.dm.jrt.core.config.InvocationConfiguration invocationConfiguration,
                @org.jetbrains.annotations.NotNull final com.github.dm.jrt.object.config.ObjectConfiguration objectConfiguration,
                @org.jetbrains.annotations.NotNull final com.github.dm.jrt.android.core.config.LoaderConfiguration loaderConfiguration) {
            return new ${generatedClassName}${genericTypes}(mContext, mTarget, invocationConfiguration, objectConfiguration, loaderConfiguration);
        }
    }
