/*-
 * ============LICENSE_START=======================================================
 * OSAM
 * ================================================================================
 * Copyright (C) 2018 AT&T
 * ================================================================================
 * 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.
 * ============LICENSE_END=========================================================
 */



package org.onap.osam.config;

import org.hibernate.SessionFactory;
import org.mockito.Mockito;
import org.onap.osam.services.IAsyncInstantiationBusinessLogic;
import org.onap.portalsdk.core.service.DataAccessService;
import org.onap.osam.aai.AaiClientInterface;
import org.onap.osam.aai.util.HttpsAuthClient;
import org.onap.osam.aai.util.SSLContextProvider;
import org.onap.osam.aai.util.SystemPropertyHelper;
import org.onap.osam.job.JobAdapter;
import org.onap.osam.job.JobsBrokerService;
import org.onap.osam.job.command.InProgressStatusCommand;
import org.onap.osam.job.command.JobCommandFactory;
import org.onap.osam.job.command.ServiceInstantiationCommand;
import org.onap.osam.job.impl.JobAdapterImpl;
import org.onap.osam.job.impl.JobWorker;
import org.onap.osam.job.impl.JobsBrokerServiceInDatabaseImpl;
import org.onap.osam.mso.RestMsoImplementation;
import org.onap.osam.services.AsyncInstantiationBusinessLogicImpl;
import org.onap.osam.services.IAuditService;
import org.onap.osam.services.AuditServiceImpl;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class JobCommandsConfigWithMockedMso {

    @Bean
    public RestMsoImplementation restMso() {
        return Mockito.mock(RestMsoImplementation.class);
    }

    @Bean
    public JobsBrokerService jobsBrokerService(DataAccessService dataAccessService, SessionFactory sessionFactory) {
        return new JobsBrokerServiceInDatabaseImpl(dataAccessService, sessionFactory, 200, 0);
    }

    @Bean
    public HttpsAuthClient httpsAuthClientFactory(){
        return new HttpsAuthClient("some random path", new SystemPropertyHelper(), new SSLContextProvider());
    }

    @Bean
    public JobAdapter jobAdapter() {
        return new JobAdapterImpl();
    }

    @Bean
    public JobCommandFactory jobCommandFactory(ApplicationContext applicationContext) {
        return new JobCommandFactory(applicationContext);
    }

    @Bean
    public JobWorker jobWorker(JobsBrokerService jobsBrokerService, JobCommandFactory jobCommandFactory) {
        JobWorker jobWorker = new JobWorker();
        jobWorker.setJobsBrokerService(jobsBrokerService);
        jobWorker.setJobCommandFactory(jobCommandFactory);
        return jobWorker;
    }

    @Bean
    public IAsyncInstantiationBusinessLogic asyncInstantiationBusinessLogic(DataAccessService dataAccessService,
                                                                            JobAdapter jobAdapter,
                                                                            JobsBrokerService jobsBrokerService,
                                                                            SessionFactory sessionFactory,
                                                                            AaiClientInterface aaiClient) {
        return new AsyncInstantiationBusinessLogicImpl(dataAccessService, jobAdapter, jobsBrokerService, sessionFactory, aaiClient);
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public ServiceInstantiationCommand serviceInstantiationCommand() {
        return new ServiceInstantiationCommand();
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public InProgressStatusCommand inProgressStatusCommand() {
        return new InProgressStatusCommand();
    }

    @Bean
    public IAuditService auditService() {
        return new AuditServiceImpl();
    }

}
