/**
 * 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
 *
 *      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 org.apache.camel.component.optaplanner;

import java.util.concurrent.ExecutorService;

import org.apache.camel.Exchange;
import org.apache.camel.impl.DefaultProducer;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.solver.ProblemFactChange;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OptaPlannerProducer extends DefaultProducer {

    private static final transient Logger LOGGER = LoggerFactory.getLogger(OptaPlannerProducer.class);

    private ExecutorService executor;
    private final OptaPlannerEndpoint endpoint;
    private final OptaPlannerConfiguration configuration;

    public OptaPlannerProducer(OptaPlannerEndpoint endpoint, OptaPlannerConfiguration configuration) {
        super(endpoint);
        this.endpoint = endpoint;
        this.configuration = configuration;
    }

    @Override
    protected void doStart() throws Exception {
        if (configuration.isAsync()) {
            executor = endpoint.getCamelContext().getExecutorServiceManager().newFixedThreadPool(
                    this, endpoint.getEndpointUri(), configuration.getThreadPoolSize());
        }
        super.doStart();
    }

    @Override
    protected void doStop() throws Exception {
        if (executor != null) {
            endpoint.getCamelContext().getExecutorServiceManager().shutdown(executor);
            executor = null;
        }
        super.doStop();
    }

    @Override
    public synchronized void process(Exchange exchange) throws Exception {
        final Object body = exchange.getIn().getMandatoryBody();
        final String solverId = getSolverId(exchange);

        if (body instanceof Solution) {
            if (isAsync(exchange)) {
                LOGGER.debug("Asynchronously solving problem: [{}] with id [{}]", body, solverId);
                final Solver solver = endpoint.getOrCreateSolver(solverId);
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            solver.solve((Solution) body);
                        } catch (Throwable e) {
                            LOGGER.error("Asynchronously solving failed for solverId ({})", solverId, e);
                        }
                    }
                });
            } else {
                LOGGER.debug("Synchronously solving problem: [{}] with id [{}]", body, solverId);
                Solver solver = endpoint.getSolver(solverId);
                if (solver == null) {
                    solver = endpoint.createSolver();
                }
                solver.solve((Solution) body);
                populateResult(exchange, solver);
            }
        } else if (body instanceof ProblemFactChange) {
            LOGGER.debug("Adding ProblemFactChange to solver: [{}] with id [{}]", body, solverId);
            Solver solver = endpoint.getOrCreateSolver(solverId);
            solver.addProblemFactChange((ProblemFactChange)body);
            if (!isAsync(exchange)) {
                while (!solver.isEveryProblemFactChangeProcessed()) {
                    Thread.sleep(100);
                }
            }
            populateResult(exchange, solver);
        } else {
            LOGGER.debug("Retrieving best score for solver: [{}]", solverId);
            Solver solver = endpoint.getSolver(solverId);
            if (solver == null) {
                throw new RuntimeException("Solver not found: " + solverId);
            }
            populateResult(exchange, solver);
        }
    }

    private void populateResult(Exchange exchange, Solver solver) {
        exchange.getIn().setBody(solver.getBestSolution());
        exchange.getIn().setHeader(OptaPlannerConstants.TIME_SPENT, solver.getTimeMillisSpent());
        exchange.getIn().setHeader(OptaPlannerConstants.IS_EVERY_PROBLEM_FACT_CHANGE_PROCESSED, solver.isEveryProblemFactChangeProcessed());
        exchange.getIn().setHeader(OptaPlannerConstants.IS_TERMINATE_EARLY, solver.isTerminateEarly());
        exchange.getIn().setHeader(OptaPlannerConstants.IS_SOLVING, solver.isSolving());
    }

    private String getSolverId(Exchange exchange) throws Exception {
        String solverId = exchange.getIn().getHeader(OptaPlannerConstants.SOLVER_ID, String.class);
        if (solverId == null) {
            solverId = configuration.getSolverId();
        }
        LOGGER.debug("SolverId: [{}]", solverId);
        return solverId;
    }

    private boolean isAsync(Exchange exchange) {
        Boolean isAsync = exchange.getIn().getHeader(OptaPlannerConstants.IS_ASYNC, Boolean.class);
        return isAsync != null ? isAsync : configuration.isAsync();
    }
}
