/*
 * Copyright 2017 The Mifos Initiative.
 *
 * 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 io.mifos.portfolio.service.internal.command.handler;

import io.mifos.core.command.annotation.Aggregate;
import io.mifos.core.command.annotation.CommandHandler;
import io.mifos.core.command.annotation.CommandLogLevel;
import io.mifos.core.command.annotation.EventEmitter;
import io.mifos.core.lang.ServiceException;
import io.mifos.portfolio.api.v1.domain.ChargeDefinition;
import io.mifos.portfolio.api.v1.events.ChargeDefinitionEvent;
import io.mifos.portfolio.api.v1.events.EventConstants;
import io.mifos.portfolio.service.internal.command.ChangeChargeDefinitionCommand;
import io.mifos.portfolio.service.internal.command.CreateChargeDefinitionCommand;
import io.mifos.portfolio.service.internal.command.DeleteProductChargeDefinitionCommand;
import io.mifos.portfolio.service.internal.mapper.ChargeDefinitionMapper;
import io.mifos.portfolio.service.internal.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * @author Myrle Krantz
 */
@Aggregate
public class ChargeDefinitionCommandHandler {
  private final ProductRepository productRepository;
  private final ChargeDefinitionRepository chargeDefinitionRepository;
  private final BalanceSegmentRepository balanceSegmentRepository;

  @Autowired
  public ChargeDefinitionCommandHandler(
      final ProductRepository productRepository,
      final ChargeDefinitionRepository chargeDefinitionRepository,
      final BalanceSegmentRepository balanceSegmentRepository) {
    this.productRepository = productRepository;
    this.chargeDefinitionRepository = chargeDefinitionRepository;
    this.balanceSegmentRepository = balanceSegmentRepository;
  }

  @SuppressWarnings("unused")
  @Transactional
  @CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_CHARGE_DEFINITION)
  public ChargeDefinitionEvent process(final CreateChargeDefinitionCommand command) {
    final ChargeDefinition chargeDefinition = command.getInstance();
    final String productIdentifier = command.getProductIdentifier();

    final ProductEntity productEntity
            = productRepository.findByIdentifier(productIdentifier)
            .orElseThrow(() -> ServiceException.badRequest("The given product identifier does not refer to a product {0}", productIdentifier));

    final SegmentRange segmentRange = getSegmentRange(chargeDefinition, productIdentifier);

    final ChargeDefinitionEntity chargeDefinitionEntity =
            ChargeDefinitionMapper.map(productEntity, chargeDefinition, segmentRange.fromSegment, segmentRange.toSegment);
    chargeDefinitionRepository.save(chargeDefinitionEntity);

    return new ChargeDefinitionEvent(
            command.getProductIdentifier(),
            command.getInstance().getIdentifier());
  }

  @SuppressWarnings("unused")
  @Transactional
  @CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_CHARGE_DEFINITION)
  public ChargeDefinitionEvent process(final ChangeChargeDefinitionCommand command) {
    final ChargeDefinition chargeDefinition = command.getInstance();
    final String productIdentifier = command.getProductIdentifier();

    final ChargeDefinitionEntity existingChargeDefinition
            = chargeDefinitionRepository.findByProductIdAndChargeDefinitionIdentifier(productIdentifier, chargeDefinition.getIdentifier())
            .orElseThrow(() -> ServiceException.internalError("task definition not found."));

    final SegmentRange segmentRange = getSegmentRange(chargeDefinition, productIdentifier);

    final ChargeDefinitionEntity chargeDefinitionEntity =
            ChargeDefinitionMapper.map(existingChargeDefinition.getProduct(), chargeDefinition, segmentRange.fromSegment, segmentRange.toSegment);
    chargeDefinitionEntity.setId(existingChargeDefinition.getId());
    chargeDefinitionEntity.setId(existingChargeDefinition.getId());
    chargeDefinitionRepository.save(chargeDefinitionEntity);

    return new ChargeDefinitionEvent(
            command.getProductIdentifier(),
            command.getInstance().getIdentifier());
  }

  @SuppressWarnings("unused")
  @Transactional
  @CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.DELETE_PRODUCT_CHARGE_DEFINITION)
  public ChargeDefinitionEvent process(final DeleteProductChargeDefinitionCommand command) {
    final ChargeDefinitionEntity toDelete = chargeDefinitionRepository.findByProductIdAndChargeDefinitionIdentifier(
            command.getProductIdentifier(),
            command.getChargeDefinitionIdentifier())
            .orElseThrow(() -> ServiceException.notFound("Charge definition not found for product identifier ''{0}'' and charge definition identifier ''{1}''.",
                    command.getProductIdentifier(), command.getChargeDefinitionIdentifier()));

    chargeDefinitionRepository.delete(toDelete);

    return new ChargeDefinitionEvent(
            command.getProductIdentifier(),
            command.getChargeDefinitionIdentifier());
  }

  static class SegmentRange {
    final BalanceSegmentEntity fromSegment;
    final BalanceSegmentEntity toSegment;

    SegmentRange(final BalanceSegmentEntity fromSegment, final BalanceSegmentEntity toSegment) {
      this.fromSegment = fromSegment;
      this.toSegment = toSegment;
    }
  }

  private SegmentRange getSegmentRange(final ChargeDefinition chargeDefinition, final String productIdentifier) {
    if (chargeDefinition.getForSegmentSet() != null) {
      final Optional<BalanceSegmentEntity> fromSegmentOptional =
          balanceSegmentRepository.findByProductIdentifierAndSegmentSetIdentifierAndSegmentIdentifier(
              productIdentifier,
              chargeDefinition.getForSegmentSet(),
              chargeDefinition.getFromSegment());
      final Optional<BalanceSegmentEntity> toSegmentOptional =
          balanceSegmentRepository.findByProductIdentifierAndSegmentSetIdentifierAndSegmentIdentifier(
              productIdentifier,
              chargeDefinition.getForSegmentSet(),
              chargeDefinition.getFromSegment());

      if (fromSegmentOptional.isPresent() && toSegmentOptional.isPresent()) {
        return new SegmentRange(fromSegmentOptional.get(), toSegmentOptional.get());
      }
    }

    return new SegmentRange(null, null);
  }
}
