/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.android.build.gradle.model;

import static com.android.build.gradle.model.ModelConstants.IS_APPLICATION;
import static com.android.build.gradle.model.ModelConstants.TASK_MANAGER;

import com.android.build.gradle.AndroidConfig;
import com.android.build.gradle.internal.DependencyManager;
import com.android.build.gradle.internal.ExtraModelInfo;
import com.android.build.gradle.internal.SdkHandler;
import com.android.build.gradle.internal.TaskManager;
import com.android.build.gradle.internal.ndk.NdkHandler;
import com.android.build.gradle.internal.profile.ProfilerInitializer;
import com.android.build.gradle.internal.variant.ApplicationVariantFactory;
import com.android.build.gradle.internal.variant.VariantFactory;
import com.android.builder.Version;
import com.android.builder.core.AndroidBuilder;
import com.android.builder.profile.ProcessRecorder;
import com.google.wireless.android.sdk.stats.AndroidStudioStats;

import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.internal.reflect.Instantiator;
import org.gradle.internal.service.ServiceRegistry;
import org.gradle.model.Model;
import org.gradle.model.RuleSource;
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry;

import android.databinding.tool.DataBindingBuilder;

/**
 * Gradle component model plugin class for 'application' projects.
 */
public class AppComponentModelPlugin implements Plugin<Project> {

    @Override
    public void apply(Project project) {
        ProfilerInitializer.init(project);
        ProcessRecorder.getProject(project.getPath())
                .setAndroidPluginVersion(Version.ANDROID_GRADLE_PLUGIN_VERSION)
                .setAndroidPlugin(
                        AndroidStudioStats.GradleBuildProject.PluginType.APPLICATION)
                .setPluginGeneration(
                        AndroidStudioStats.GradleBuildProject.PluginGeneration.COMPONENT_MODEL);

        project.getPluginManager().apply(BaseComponentModelPlugin.class);

        project.getPluginManager().apply(AndroidComponentModelTestPlugin.class);
    }

    public static class Rules extends RuleSource {

        @SuppressWarnings("NonBooleanMethodNameMayNotStartWithQuestion")
        @Model(IS_APPLICATION)
        public static Boolean isApplication() {
            return true;
        }

        @Model(TASK_MANAGER)
        public static TaskManager createTaskManager(
                AndroidConfig androidExtension,
                Project project,
                AndroidBuilder androidBuilder,
                DataBindingBuilder dataBindingBuilder,
                SdkHandler sdkHandler,
                NdkHandler ndkHandler,
                ExtraModelInfo extraModelInfo,
                ToolingModelBuilderRegistry toolingRegistry) {
            DependencyManager dependencyManager = new DependencyManager(
                    project,
                    extraModelInfo,
                    sdkHandler);

            return new ApplicationComponentTaskManager(
                    project,
                    androidBuilder,
                    dataBindingBuilder,
                    androidExtension,
                    sdkHandler,
                    ndkHandler,
                    dependencyManager,
                    toolingRegistry);
        }

        @Model
        public static VariantFactory createVariantFactory(
                ServiceRegistry serviceRegistry,
                AndroidBuilder androidBuilder,
                AndroidConfig extension) {
            Instantiator instantiator = serviceRegistry.get(Instantiator.class);
            return new ApplicationVariantFactory(instantiator, androidBuilder, extension);
        }
    }
}
