/*
 * 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.hazelcast.atomicnumber;

import java.util.Map;

import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IAtomicLong;
import org.apache.camel.Exchange;
import org.apache.camel.component.hazelcast.HazelcastComponentHelper;
import org.apache.camel.component.hazelcast.HazelcastConstants;
import org.apache.camel.component.hazelcast.HazelcastDefaultEndpoint;
import org.apache.camel.component.hazelcast.HazelcastDefaultProducer;
import org.apache.camel.component.hazelcast.HazelcastOperation;
import org.apache.camel.util.ObjectHelper;

public class HazelcastAtomicnumberProducer extends HazelcastDefaultProducer {

    private final IAtomicLong atomicnumber;

    public HazelcastAtomicnumberProducer(HazelcastInstance hazelcastInstance, HazelcastDefaultEndpoint endpoint, String cacheName) {
        super(endpoint);
        this.atomicnumber = hazelcastInstance.getAtomicLong(cacheName);
    }

    @Override
    public void process(Exchange exchange) throws Exception {

        Map<String, Object> headers = exchange.getIn().getHeaders();
        
        long expectedValue = 0L;
        
        if (headers.containsKey(HazelcastConstants.EXPECTED_VALUE)) {
            expectedValue = (long) headers.get(HazelcastConstants.EXPECTED_VALUE);
        }
        
        HazelcastOperation operation = lookupOperation(exchange);

        switch (operation) {

        case INCREMENT:
            this.increment(exchange);
            break;

        case DECREMENT:
            this.decrement(exchange);
            break;
            
        case COMPARE_AND_SET:
            this.compare(expectedValue, exchange);
            break;
            
        case GET_AND_ADD:
            this.getAndAdd(exchange);
            break;

        case SET_VALUE:
            this.set(exchange);
            break;

        case GET:
            this.get(exchange);
            break;

        case DESTROY:
            this.destroy();
            break;

        default:
            throw new IllegalArgumentException(String.format("The value '%s' is not allowed for parameter '%s' on the ATOMICNUMBER.", operation, HazelcastConstants.OPERATION));
        }

        // finally copy headers
        HazelcastComponentHelper.copyHeaders(exchange);
    }

    private void get(Exchange exchange) {
        exchange.getOut().setBody(this.atomicnumber.get());
    }

    private void increment(Exchange exchange) {
        exchange.getOut().setBody(this.atomicnumber.incrementAndGet());
    }

    private void decrement(Exchange exchange) {
        exchange.getOut().setBody(this.atomicnumber.decrementAndGet());
    }
    
    private void compare(long expected, Exchange exchange) {
        long update = exchange.getIn().getBody(Long.class);
        if (ObjectHelper.isEmpty(expected)) {
            throw new IllegalArgumentException("Expected value must be specified");
        }
        exchange.getOut().setBody(this.atomicnumber.compareAndSet(expected, update));
    }
    
    private void getAndAdd(Exchange exchange) {
        long delta = exchange.getIn().getBody(Long.class);
        exchange.getOut().setBody(this.atomicnumber.getAndAdd(delta));
    }

    private void set(Exchange exchange) {
        this.atomicnumber.set(exchange.getIn().getBody(Long.class));
    }

    private void destroy() {
        this.atomicnumber.destroy();
    }

}
