/*
 * 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.cache.query.cq.internal.command;

import java.io.IOException;
import java.util.Set;

import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.operations.ExecuteCQOperationContext;
import org.apache.geode.cache.query.CqException;
import org.apache.geode.cache.query.Query;
import org.apache.geode.cache.query.cq.internal.CqServiceImpl;
import org.apache.geode.cache.query.cq.internal.ServerCQImpl;
import org.apache.geode.cache.query.internal.DefaultQuery;
import org.apache.geode.cache.query.internal.DefaultQueryService;
import org.apache.geode.cache.query.internal.cq.CqServiceProvider;
import org.apache.geode.distributed.internal.DistributionStats;
import org.apache.geode.internal.cache.tier.Acceptor;
import org.apache.geode.internal.cache.tier.CachedRegionHelper;
import org.apache.geode.internal.cache.tier.Command;
import org.apache.geode.internal.cache.tier.MessageType;
import org.apache.geode.internal.cache.tier.sockets.CacheClientNotifier;
import org.apache.geode.internal.cache.tier.sockets.CacheClientProxy;
import org.apache.geode.internal.cache.tier.sockets.CacheServerStats;
import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
import org.apache.geode.internal.cache.tier.sockets.Message;
import org.apache.geode.internal.cache.tier.sockets.Part;
import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
import org.apache.geode.internal.cache.vmotion.VMotionObserver;
import org.apache.geode.internal.cache.vmotion.VMotionObserverHolder;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.internal.security.AuthorizeRequest;
import org.apache.geode.internal.security.SecurityService;
import org.apache.geode.security.ResourcePermission.Operation;
import org.apache.geode.security.ResourcePermission.Resource;

/**
 * @since GemFire 6.1
 */
public class ExecuteCQ61 extends BaseCQCommand {
  protected static final Logger logger = LogService.getLogger();

  private static final ExecuteCQ61 singleton = new ExecuteCQ61();

  public static Command getCommand() {
    return singleton;
  }

  private ExecuteCQ61() {
    // nothing
  }

  @Override
  public void cmdExecute(final Message clientMessage, final ServerConnection serverConnection,
      final SecurityService securityService, long start) throws IOException, InterruptedException {
    Acceptor acceptor = serverConnection.getAcceptor();
    CachedRegionHelper crHelper = serverConnection.getCachedRegionHelper();
    ClientProxyMembershipID id = serverConnection.getProxyID();
    CacheServerStats stats = serverConnection.getCacheServerStats();

    serverConnection.setAsTrue(REQUIRES_RESPONSE);
    serverConnection.setAsTrue(REQUIRES_CHUNKED_RESPONSE);

    // Retrieve the data from the message parts
    String cqName = clientMessage.getPart(0).getString();
    String cqQueryString = clientMessage.getPart(1).getString();
    int cqState = clientMessage.getPart(2).getInt();

    Part isDurablePart = clientMessage.getPart(3);
    byte[] isDurableByte = isDurablePart.getSerializedForm();
    boolean isDurable = !(isDurableByte == null || isDurableByte[0] == 0);
    // region data policy
    Part regionDataPolicyPart = clientMessage.getPart(clientMessage.getNumberOfParts() - 1);
    byte[] regionDataPolicyPartBytes = regionDataPolicyPart.getSerializedForm();
    if (logger.isDebugEnabled()) {
      logger.debug("{}: Received {} request from {} CqName: {} queryString: {}",
          serverConnection.getName(), MessageType.getString(clientMessage.getMessageType()),
          serverConnection.getSocketString(), cqName, cqQueryString);
    }

    // Check if the Server is running in NotifyBySubscription=true mode.
    CacheClientNotifier ccn = acceptor.getCacheClientNotifier();
    if (ccn != null) {
      CacheClientProxy proxy = ccn.getClientProxy(id);
      if (proxy != null && !proxy.isNotifyBySubscription()) {
        // This should have been taken care at the client.
        String err =
            "Server notifyBySubscription mode is set to false. CQ execution is not supported in this mode.";
        sendCqResponse(MessageType.CQDATAERROR_MSG_TYPE, err, clientMessage.getTransactionId(),
            null, serverConnection);
        return;
      }
    }

    DefaultQueryService qService = null;
    CqServiceImpl cqServiceForExec = null;
    Query query = null;
    Set cqRegionNames = null;
    ExecuteCQOperationContext executeCQContext = null;
    ServerCQImpl cqQuery = null;

    try {
      qService = (DefaultQueryService) crHelper.getCache().getLocalQueryService();

      // Authorization check
      AuthorizeRequest authzRequest = serverConnection.getAuthzRequest();
      query = qService.newQuery(cqQueryString);
      cqRegionNames = ((DefaultQuery) query).getRegionsInQuery(null);
      if (authzRequest != null) {
        executeCQContext = authzRequest.executeCQAuthorize(cqName, cqQueryString, cqRegionNames);
        String newCqQueryString = executeCQContext.getQuery();

        if (!cqQueryString.equals(newCqQueryString)) {
          query = qService.newQuery(newCqQueryString);
          cqQueryString = newCqQueryString;
          cqRegionNames = executeCQContext.getRegionNames();
          if (cqRegionNames == null) {
            cqRegionNames = ((DefaultQuery) query).getRegionsInQuery(null);
          }
        }
      }

      // auth check to see if user can create CQ or not
      ((DefaultQuery) query).getRegionsInQuery(null).forEach((regionName) -> securityService
          .authorize(Resource.DATA, Operation.READ, (String) regionName));

      // test hook to trigger vMotion during CQ registration
      if (CqServiceProvider.VMOTION_DURING_CQ_REGISTRATION_FLAG) {
        VMotionObserver vmo = VMotionObserverHolder.getInstance();
        vmo.vMotionBeforeCQRegistration();
      }

      cqServiceForExec = (CqServiceImpl) qService.getCqService();
      // registering cq with serverConnection so that when CCP will require auth info it can access
      // that
      // registering cq auth before as possibility that you may get event
      serverConnection.setCq(cqName, isDurable);
      cqQuery = (ServerCQImpl) cqServiceForExec.executeCq(cqName, cqQueryString, cqState, id, ccn,
          isDurable, true, regionDataPolicyPartBytes[0], null);
    } catch (CqException cqe) {
      sendCqResponse(MessageType.CQ_EXCEPTION_TYPE, "", clientMessage.getTransactionId(), cqe,
          serverConnection);
      serverConnection.removeCq(cqName, isDurable);
      return;
    } catch (Exception e) {
      writeChunkedException(clientMessage, e, serverConnection);
      serverConnection.removeCq(cqName, isDurable);
      return;
    }

    boolean sendResults = false;

    if (clientMessage.getMessageType() == MessageType.EXECUTECQ_WITH_IR_MSG_TYPE) {
      sendResults = true;
    }

    // Execute the query only if it is execute with initial results or
    // if it is a non PR query with execute query and maintain keys flags set
    boolean successQuery = false;
    if (sendResults || CqServiceImpl.EXECUTE_QUERY_DURING_INIT && CqServiceProvider.MAINTAIN_KEYS
        && !cqQuery.isPR()) {
      // Execute the query and send the result-set to client.
      try {
        if (query == null) {
          query = qService.newQuery(cqQueryString);
          cqRegionNames = ((DefaultQuery) query).getRegionsInQuery(null);
        }
        ((DefaultQuery) query).setIsCqQuery(true);
        successQuery =
            processQuery(clientMessage, query, cqQueryString, cqRegionNames,
                start, cqQuery, executeCQContext, serverConnection, sendResults, securityService);


        // Update the CQ statistics.
        cqQuery.getVsdStats().setCqInitialResultsTime(DistributionStats.getStatTime() - start);
        stats.incProcessExecuteCqWithIRTime(DistributionStats.getStatTime() - start);
        // logger.fine("Time spent in execute with initial results :" +
        // DistributionStats.getStatTime() + ", " + oldstart);
      } finally { // To handle any exception.
        // If failure to execute the query, close the CQ.
        if (!successQuery) {
          try {
            cqServiceForExec.closeCq(cqName, id);
          } catch (Exception ignored) {
            // Ignore.
          }
        }
      }
    } else {
      // Don't execute query for cq.execute and
      // if it is a PR query with execute query and maintain keys flags not set
      cqQuery.cqResultKeysInitialized = true;
      successQuery = true;
    }

    if (!sendResults && successQuery) {
      // Send OK to client
      sendCqResponse(MessageType.REPLY,
          "cq created successfully.",
          clientMessage.getTransactionId(), null, serverConnection);

      long start2 = DistributionStats.getStatTime();
      stats.incProcessCreateCqTime(start2 - start);
    }
    serverConnection.setAsTrue(RESPONDED);
  }

}
