package org.apache.helix.integration;

/*
 * 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.
 */

import java.util.Date;

import org.apache.helix.ConfigAccessor;
import org.apache.helix.HelixRollbackException;
import org.apache.helix.NotificationContext;
import org.apache.helix.TestHelper;
import org.apache.helix.controller.rebalancer.strategy.CrushEdRebalanceStrategy;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
import org.apache.helix.integration.rebalancer.TestAutoRebalance;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.MasterSlaveSMD;
import org.apache.helix.model.Message;
import org.apache.helix.participant.StateMachineEngine;
import org.apache.helix.participant.statemachine.StateModel;
import org.apache.helix.participant.statemachine.StateModelFactory;
import org.apache.helix.participant.statemachine.StateModelInfo;
import org.apache.helix.participant.statemachine.Transition;
import org.apache.helix.tools.ClusterStateVerifier;
import org.apache.helix.tools.ClusterVerifiers.BestPossibleExternalViewVerifier;
import org.apache.helix.tools.ClusterVerifiers.HelixClusterVerifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class TestErrorReplicaPersist extends ZkStandAloneCMTestBase {
  @BeforeClass
  public void beforeClass() throws Exception {
    // Logger.getRootLogger().setLevel(Level.INFO);
    System.out.println("START " + CLASS_NAME + " at " + new Date(System.currentTimeMillis()));

    int numNode = NODE_NR + 1;
    _participants = new MockParticipantManager[numNode];
    // setup storage cluster
    _gSetupTool.addCluster(CLUSTER_NAME, true);
    createResourceWithDelayedRebalance(CLUSTER_NAME, TEST_DB, MasterSlaveSMD.name, _PARTITIONS,
        _replica, _replica - 1, 1800000, CrushEdRebalanceStrategy.class.getName());
    for (int i = 0; i < numNode; i++) {
      String storageNodeName = PARTICIPANT_PREFIX + "_" + (START_PORT + i);
      _gSetupTool.addInstanceToCluster(CLUSTER_NAME, storageNodeName);
    }

    _gSetupTool.rebalanceStorageCluster(CLUSTER_NAME, TEST_DB, _replica);

    // start dummy participants
    for (int i = 0; i < numNode; i++) {
      String instanceName = PARTICIPANT_PREFIX + "_" + (START_PORT + i);
      MockParticipantManager participant =
          new MockParticipantManager(ZK_ADDR, CLUSTER_NAME, instanceName);
      participant.syncStart();
      _participants[i] = participant;
    }
    enablePersistBestPossibleAssignment(_gZkClient, CLUSTER_NAME, true);
    enableDelayRebalanceInCluster(_gZkClient, CLUSTER_NAME, true, 1800000);

    // start controller
    String controllerName = CONTROLLER_PREFIX + "_0";
    _controller = new ClusterControllerManager(ZK_ADDR, CLUSTER_NAME, controllerName);
    _controller.syncStart();

    boolean result = ClusterStateVerifier.verifyByZkCallback(
        new TestAutoRebalance.ExternalViewBalancedVerifier(_gZkClient, CLUSTER_NAME, TEST_DB));

    Assert.assertTrue(result);
  }

  @AfterClass
  public void afterClass() throws Exception {
    for (MockParticipantManager participant : _participants) {
      participant.syncStop();
    }
    super.afterClass();
  }

  @Test
  public void testErrorReplicaPersist() throws InterruptedException {
    ConfigAccessor configAccessor = new ConfigAccessor(_gZkClient);
    ClusterConfig clusterConfig = configAccessor.getClusterConfig(CLUSTER_NAME);
    clusterConfig.setErrorPartitionThresholdForLoadBalance(100000);
    configAccessor.setClusterConfig(CLUSTER_NAME, clusterConfig);
    
    for (int i = 0; i < (NODE_NR + 1) / 2; i++) {
      _participants[i].syncStop();
      Thread.sleep(2000);
      String instanceName = PARTICIPANT_PREFIX + "_" + (START_PORT + i);
      MockParticipantManager participant =
          new MockParticipantManager(ZK_ADDR, CLUSTER_NAME, instanceName);
      StateMachineEngine stateMachineEngine = participant.getStateMachineEngine();
      stateMachineEngine
          .registerStateModelFactory(MasterSlaveSMD.name, new MockFailedMSStateModelFactory());
      participant.syncStart();
      _participants[i] = participant;
    }
    HelixClusterVerifier verifier =
        new BestPossibleExternalViewVerifier.Builder(CLUSTER_NAME).setZkClient(_gZkClient)
            .setWaitTillVerify(TestHelper.DEFAULT_REBALANCE_PROCESSING_WAIT_TIME)
            .build();
    Assert.assertTrue(((BestPossibleExternalViewVerifier) verifier).verifyByPolling());
    for (int i = 0; i < (NODE_NR + 1) / 2; i++) {
      _gSetupTool.getClusterManagementTool()
          .enableInstance(CLUSTER_NAME, _participants[i].getInstanceName(), false);
    }

    Assert.assertTrue(((BestPossibleExternalViewVerifier) verifier).verifyByPolling());
  }


  class MockFailedMSStateModelFactory
      extends StateModelFactory<MockFailedMSStateModel> {

    @Override
    public MockFailedMSStateModel createNewStateModel(String resourceName,
        String partitionKey) {
      MockFailedMSStateModel model = new MockFailedMSStateModel();
      return model;
    }
  }

  @StateModelInfo(initialState = "OFFLINE", states = { "MASTER", "SLAVE", "ERROR"
  })
  public static class MockFailedMSStateModel extends StateModel {
    private static Logger LOG = LoggerFactory.getLogger(MockFailedMSStateModel.class);

    public MockFailedMSStateModel() {
    }

    @Transition(to = "SLAVE", from = "OFFLINE") public void onBecomeSlaveFromOffline(
        Message message, NotificationContext context) throws IllegalAccessException {
      throw new IllegalAccessException("Failed!");
    }

    @Transition(to = "MASTER", from = "SLAVE") public void onBecomeMasterFromSlave(Message message,
        NotificationContext context) throws InterruptedException, HelixRollbackException {
      LOG.error("Become MASTER from SLAVE");
    }

    @Transition(to = "SLAVE", from = "MASTER") public void onBecomeSlaveFromMaster(Message message,
        NotificationContext context) {
      LOG.info("Become Slave from Master");
    }

    @Transition(to = "OFFLINE", from = "SLAVE") public void onBecomeOfflineFromSlave(
        Message message, NotificationContext context) {
      LOG.info("Become OFFLINE from SLAVE");
    }

    @Transition(to = "DROPPED", from = "OFFLINE") public void onBecomeDroppedFromOffline(
        Message message, NotificationContext context) {
      LOG.info("Become DROPPED FROM OFFLINE");
    }
  }

}
