/*
 * 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.geode.internal.cache;

import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Before;
import org.junit.Test;

import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.Operation;
import org.apache.geode.cache.RegionAttributes;

public class UpdateOperationJUnitTest {
  EntryEventImpl event;
  UpdateOperation.UpdateMessage message;
  DistributedRegion region;

  @Before
  public void setup() {
    event = mock(EntryEventImpl.class);
    region = mock(DistributedRegion.class);
    RegionAttributes attr = mock(RegionAttributes.class);
    CachePerfStats stats = mock(CachePerfStats.class);
    when(event.isOriginRemote()).thenReturn(false);
    when(stats.endPut(anyLong(), eq(false))).thenReturn(0L);

    message = new UpdateOperation.UpdateMessage();
    message.event = event;
    when(region.isAllEvents()).thenReturn(true);
    when(region.getAttributes()).thenReturn(attr);
    when(region.isUsedForPartitionedRegionBucket()).thenReturn(false);
    when(region.getDataPolicy()).thenReturn(DataPolicy.REPLICATE);
    when(region.getConcurrencyChecksEnabled()).thenReturn(true);
    when(region.getCachePerfStats()).thenReturn(stats);
    when(attr.getDataPolicy()).thenReturn(DataPolicy.REPLICATE);
    when(event.getOperation()).thenReturn(Operation.CREATE);
  }

  /**
   * AUO's doPutOrCreate will try with create first. If it succeed, it will not try update
   * retry update
   */
  @Test
  public void createSucceedShouldNotRetryAnymore() {
    when(region.basicUpdate(eq(event), eq(true), eq(false), anyLong(), eq(true)))
        .thenReturn(true);
    message.basicOperateOnRegion(event, region);
    verify(region, times(1)).basicUpdate(eq(event), eq(true), eq(false), anyLong(), eq(true));
    verify(region, times(0)).basicUpdate(eq(event), eq(false), eq(true), anyLong(), eq(true));
    verify(region, times(0)).basicUpdate(eq(event), eq(false), eq(false), anyLong(), eq(true));
  }

  /**
   * AUO's doPutOrCreate will try with create first. If it failed with ConcurrencyConflict, should
   * not
   * retry update
   */
  @Test
  public void createFailWithConcurrencyConflictShouldNotRetry() {
    when(region.basicUpdate(eq(event), eq(true), eq(false), anyLong(), eq(true)))
        .thenReturn(false);
    when(event.isConcurrencyConflict()).thenReturn(true);
    message.basicOperateOnRegion(event, region);
    verify(region, times(1)).basicUpdate(eq(event), eq(true), eq(false), anyLong(), eq(true));
    verify(region, times(0)).basicUpdate(eq(event), eq(false), eq(true), anyLong(), eq(true));
    verify(region, times(0)).basicUpdate(eq(event), eq(false), eq(false), anyLong(), eq(true));
  }

  /**
   * AUO's doPutOrCreate will try with create first. If it failed, it will try update.
   * If update succeed, no more retry
   */
  @Test
  public void updateSucceedShouldNotRetryAnymore() {
    when(region.basicUpdate(eq(event), eq(true), eq(false), anyLong(), eq(true)))
        .thenReturn(false);
    when(region.basicUpdate(eq(event), eq(false), eq(true), anyLong(), eq(true)))
        .thenReturn(true);
    message.basicOperateOnRegion(event, region);
    verify(region, times(1)).basicUpdate(eq(event), eq(true), eq(false), anyLong(), eq(true));
    verify(region, times(1)).basicUpdate(eq(event), eq(false), eq(true), anyLong(), eq(true));
    verify(region, times(0)).basicUpdate(eq(event), eq(false), eq(false), anyLong(), eq(true));
  }

  /**
   * AUO's doPutOrCreate() will try with create, then update.
   * If retry again, it should be an update with ifNew==false and ifOld==false
   * It should not retry with create again
   */
  @Test
  public void doPutOrCreate3rdRetryShouldBeUpdate() {
    when(region.basicUpdate(eq(event), eq(true), eq(false), anyLong(), eq(true)))
        .thenReturn(false);
    when(region.basicUpdate(eq(event), eq(false), eq(true), anyLong(), eq(true)))
        .thenReturn(false);
    message.basicOperateOnRegion(event, region);
    verify(region, times(1)).basicUpdate(eq(event), eq(true), eq(false), anyLong(), eq(true));
    verify(region, times(1)).basicUpdate(eq(event), eq(false), eq(true), anyLong(), eq(true));
    verify(region, times(1)).basicUpdate(eq(event), eq(false), eq(false), anyLong(), eq(true));
  }

}
