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

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;

import org.apache.geode.cache.AttributesMutator;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheLoaderException;
import org.apache.geode.cache.CacheStatistics;
import org.apache.geode.cache.CacheWriterException;
import org.apache.geode.cache.EntryExistsException;
import org.apache.geode.cache.EntryNotFoundException;
import org.apache.geode.cache.InterestResultPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionExistsException;
import org.apache.geode.cache.RegionService;
import org.apache.geode.cache.StatisticsDisabledException;
import org.apache.geode.cache.TimeoutException;
import org.apache.geode.cache.query.FunctionDomainException;
import org.apache.geode.cache.query.NameResolutionException;
import org.apache.geode.cache.query.QueryInvocationTargetException;
import org.apache.geode.cache.query.SelectResults;
import org.apache.geode.cache.query.TypeMismatchException;
import org.apache.geode.cache.snapshot.RegionSnapshotService;
import org.apache.geode.internal.cache.snapshot.RegionSnapshotServiceImpl;

/**
 * A wrapper class over an actual Region instance. This is used when the multiuser-authentication
 * attribute is set to true.
 *
 * @see ProxyCache
 * @since GemFire 6.5
 */
public class ProxyRegion implements Region {

  private final ProxyCache proxyCache;
  private final Region realRegion;

  public ProxyRegion(ProxyCache proxyCache, Region realRegion) {
    this.proxyCache = proxyCache;
    this.realRegion = realRegion;
  }

  @Override
  public void becomeLockGrantor() {
    throw new UnsupportedOperationException();
  }

  @Override
  public void clear() {
    try {
      preOp();
      this.realRegion.clear();
    } finally {
      postOp();
    }
  }

  @Override
  public void close() {
    try {
      preOp();
      this.realRegion.close();
    } finally {
      postOp();
    }
  }

  @Override
  public boolean containsKey(Object key) {
    try {
      preOp();
      return this.realRegion.containsKey(key);
    } finally {
      postOp();
    }
  }

  @Override
  public boolean containsKeyOnServer(Object key) {
    try {
      preOp();
      return this.realRegion.containsKeyOnServer(key);
    } finally {
      postOp();
    }
  }

  @Override
  public int sizeOnServer() {
    try {
      preOp();
      return this.realRegion.sizeOnServer();
    } finally {
      postOp();
    }
  }

  @Override
  public boolean isEmptyOnServer() {
    try {
      preOp();
      return this.realRegion.isEmptyOnServer();
    } finally {
      postOp();
    }
  }

  @Override
  public boolean containsValue(Object value) {
    try {
      preOp();
      return this.realRegion.containsValue(value);
    } finally {
      postOp();
    }
  }

  @Override
  public boolean containsValueForKey(Object key) {
    try {
      preOp();
      return this.realRegion.containsValueForKey(key);
    } finally {
      postOp();
    }
  }

  @Override
  public void create(Object key, Object value)
      throws TimeoutException, EntryExistsException, CacheWriterException {
    try {
      preOp();
      this.realRegion.create(key, value);
    } finally {
      postOp();
    }
  }

  @Override
  public void create(Object key, Object value, Object callbackArgument)
      throws TimeoutException, EntryExistsException, CacheWriterException {
    try {
      preOp();
      this.realRegion.create(key, value, callbackArgument);
    } finally {
      postOp();
    }
  }

  @Override
  public Region createSubregion(String subregionName, RegionAttributes regionAttributes)
      throws RegionExistsException, TimeoutException {
    throw new UnsupportedOperationException();
  }

  @Override
  public Object destroy(Object key)
      throws TimeoutException, EntryNotFoundException, CacheWriterException {
    try {
      preOp();
      return this.realRegion.destroy(key);
    } finally {
      postOp();
    }
  }

  @Override
  public Object destroy(Object key, Object callbackArgument)
      throws TimeoutException, EntryNotFoundException, CacheWriterException {
    try {
      preOp();
      return this.realRegion.destroy(key, callbackArgument);
    } finally {
      postOp();
    }
  }

  @Override
  public void destroyRegion() throws CacheWriterException, TimeoutException {
    try {
      preOp();
      this.realRegion.destroyRegion();
    } finally {
      postOp();
    }
  }

  @Override
  public void destroyRegion(Object callbackArgument) throws CacheWriterException, TimeoutException {
    try {
      preOp();
      this.realRegion.destroyRegion(callbackArgument);
    } finally {
      postOp();
    }
  }

  @Override
  public Set entrySet(boolean recursive) {
    try {
      preOp();
      return this.realRegion.entrySet(recursive);
    } finally {
      postOp();
    }
  }

  @Override
  public Set entrySet() {
    try {
      preOp();
      return this.realRegion.entrySet();
    } finally {
      postOp();
    }
  }

  @Override
  public boolean existsValue(String queryPredicate) throws FunctionDomainException,
      TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
    try {
      preOp();
      return this.realRegion.existsValue(queryPredicate);
    } finally {
      postOp();
    }
  }

  @Override
  public void forceRolling() {
    throw new UnsupportedOperationException();
  }

  @Override
  public Object get(Object key) throws CacheLoaderException, TimeoutException {
    try {
      preOp();
      return this.realRegion.get(key);
    } finally {
      postOp();
    }
  }

  @Override
  public Object get(Object key, Object callbackArgument)
      throws TimeoutException, CacheLoaderException {
    try {
      preOp();
      return this.realRegion.get(key, callbackArgument);
    } finally {
      postOp();
    }
  }

  @Override
  public Map getAll(Collection keys) {
    return getAll(keys, null);
  }

  @Override
  public Map getAll(Collection keys, Object callback) {
    try {
      preOp();
      return this.realRegion.getAll(keys, callback);
    } finally {
      postOp();
    }
  }

  @Override
  public RegionAttributes getAttributes() {
    return realRegion.getAttributes();
  }

  @Override
  public AttributesMutator getAttributesMutator() {
    throw new UnsupportedOperationException();
  }

  @Override
  public Cache getCache() {
    throw new UnsupportedOperationException();
  }

  @Override
  public RegionService getRegionService() {
    return this.proxyCache;
  }

  public ProxyCache getAuthenticatedCache() {
    return this.proxyCache;
  }

  @Override
  public Lock getDistributedLock(Object key) throws IllegalStateException {
    throw new UnsupportedOperationException();
  }

  @Override
  public Entry getEntry(Object key) {
    try {
      preOp();
      return this.realRegion.getEntry(key);
    } finally {
      postOp();
    }
  }

  @Override
  public String getFullPath() {
    return this.realRegion.getFullPath();
  }

  @Override
  public List getInterestList() {
    throw new UnsupportedOperationException();
  }

  @Override
  public List getInterestListRegex() {
    throw new UnsupportedOperationException();
  }

  @Override
  public String getName() {
    return this.realRegion.getName();
  }

  @Override
  public Region getParentRegion() {
    return this.realRegion.getParentRegion();
  }

  @Override
  public Lock getRegionDistributedLock() throws IllegalStateException {
    throw new UnsupportedOperationException();
  }

  @Override
  public CacheStatistics getStatistics() throws StatisticsDisabledException {
    return this.realRegion.getStatistics();
  }

  @Override
  public Region getSubregion(String path) {
    Region region = this.realRegion.getSubregion(path);
    return region != null ? new ProxyRegion(this.proxyCache, region) : null;
  }

  @Override
  public Object getUserAttribute() {
    return this.realRegion.getUserAttribute();
  }

  @Override
  public void invalidate(Object key) throws TimeoutException, EntryNotFoundException {
    try {
      preOp();
      this.realRegion.invalidate(key);
    } finally {
      postOp();
    }
  }

  @Override
  public void invalidate(Object key, Object callbackArgument)
      throws TimeoutException, EntryNotFoundException {
    try {
      preOp();
      this.realRegion.invalidate(key, callbackArgument);
    } finally {
      postOp();
    }
  }

  @Override
  public void invalidateRegion() throws TimeoutException {
    try {
      preOp();
      this.realRegion.invalidateRegion();
    } finally {
      postOp();
    }
  }

  @Override
  public void invalidateRegion(Object callbackArgument) throws TimeoutException {
    try {
      preOp();
      this.realRegion.invalidateRegion(callbackArgument);
    } finally {
      postOp();
    }
  }

  @Override
  public boolean isDestroyed() {
    return this.realRegion.isDestroyed();
  }

  @Override
  public boolean isEmpty() {
    return this.realRegion.isEmpty();
  }

  @Override
  public Set keySetOnServer() {
    try {
      preOp();
      return this.realRegion.keySetOnServer();
    } finally {
      postOp();
    }
  }

  @Override
  public Set keySet() {
    try {
      preOp();
      return this.realRegion.keySet();
    } finally {
      postOp();
    }
  }

  @Override
  public void loadSnapshot(InputStream inputStream)
      throws IOException, ClassNotFoundException, CacheWriterException, TimeoutException {
    throw new UnsupportedOperationException();
  }

  @Override
  public void localClear() {
    throw new UnsupportedOperationException(
        "Local operations are not supported when multiuser-authentication is true.");
  }

  @Override
  public void localDestroy(Object key) throws EntryNotFoundException {
    throw new UnsupportedOperationException(
        "Local operations are not supported when multiuser-authentication is true.");
  }

  @Override
  public void localDestroy(Object key, Object callbackArgument) throws EntryNotFoundException {
    throw new UnsupportedOperationException(
        "Local operations are not supported when multiuser-authentication is true.");
  }

  @Override
  public void localDestroyRegion() {
    throw new UnsupportedOperationException(
        "Local operations are not supported when multiuser-authentication is true.");
  }

  @Override
  public void localDestroyRegion(Object callbackArgument) {
    throw new UnsupportedOperationException(
        "Local operations are not supported when multiuser-authentication is true.");
  }

  @Override
  public void localInvalidate(Object key) throws EntryNotFoundException {
    throw new UnsupportedOperationException(
        "Local operations are not supported when multiuser-authentication is true.");
  }

  @Override
  public void localInvalidate(Object key, Object callbackArgument) throws EntryNotFoundException {
    throw new UnsupportedOperationException(
        "Local operations are not supported when multiuser-authentication is true.");
  }

  @Override
  public void localInvalidateRegion() {
    throw new UnsupportedOperationException(
        "Local operations are not supported when multiuser-authentication is true.");
  }

  @Override
  public void localInvalidateRegion(Object callbackArgument) {
    throw new UnsupportedOperationException(
        "Local operations are not supported when multiuser-authentication is true.");
  }

  @Override
  public Object put(Object key, Object value) throws TimeoutException, CacheWriterException {
    try {
      preOp();
      return this.realRegion.put(key, value);
    } finally {
      postOp();
    }
  }

  @Override
  public Object put(Object key, Object value, Object callbackArgument)
      throws TimeoutException, CacheWriterException {
    try {
      preOp();
      return this.realRegion.put(key, value, callbackArgument);
    } finally {
      postOp();
    }
  }

  @Override
  public void putAll(Map map) {
    putAll(map, null);
  }

  @Override
  public void putAll(Map map, Object callbackArg) {
    try {
      preOp();
      this.realRegion.putAll(map, callbackArg);
    } finally {
      postOp();
    }
  }

  @Override
  public SelectResults query(String queryPredicate) throws FunctionDomainException,
      TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
    try {
      preOp();
      return this.realRegion.query(queryPredicate);
    } finally {
      postOp();
    }
  }

  @Override
  public void registerInterest(Object key) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterest(Object key, InterestResultPolicy policy) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterest(Object key, boolean isDurable) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterest(Object key, boolean isDurable, boolean receiveValues) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterest(Object key, InterestResultPolicy policy, boolean isDurable,
      boolean receiveValues) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterest(Object key, InterestResultPolicy policy, boolean isDurable) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterestRegex(String regex) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterestRegex(String regex, InterestResultPolicy policy) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterestRegex(String regex, boolean isDurable) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterestRegex(String regex, boolean isDurable, boolean receiveValues) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterestRegex(String regex, InterestResultPolicy policy, boolean isDurable) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void registerInterestRegex(String regex, InterestResultPolicy policy, boolean isDurable,
      boolean receiveValues) {
    throw new UnsupportedOperationException();
  }

  @Override
  public Object remove(Object key) {
    try {
      preOp();
      return this.realRegion.remove(key);
    } finally {
      postOp();
    }
  }

  @Override
  public void saveSnapshot(OutputStream outputStream) throws IOException {
    throw new UnsupportedOperationException();
  }

  @Override
  public Object selectValue(String queryPredicate) throws FunctionDomainException,
      TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
    try {
      preOp();
      return this.realRegion.selectValue(queryPredicate);
    } finally {
      postOp();
    }
  }

  @Override
  public void setUserAttribute(Object value) {
    throw new UnsupportedOperationException();
  }

  @Override
  public int size() {
    try {
      preOp();
      return this.realRegion.size();
    } finally {
      postOp();
    }
  }

  @Override
  public Set subregions(boolean recursive) {
    return this.realRegion.subregions(recursive);
  }

  @Override
  public void unregisterInterest(Object key) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void unregisterInterestRegex(String regex) {
    throw new UnsupportedOperationException();
  }

  @Override
  public Collection values() {
    try {
      preOp();
      return this.realRegion.values();
    } finally {
      postOp();
    }
  }

  @Override
  public void writeToDisk() {
    throw new UnsupportedOperationException();
  }

  private void preOp() {
    if (this.proxyCache.isClosed()) {
      throw proxyCache.getCacheClosedException("Cache is closed for this user.");
    }
    UserAttributes.userAttributes.set(this.proxyCache.getUserAttributes());
  }

  private void postOp() {
    this.proxyCache.setUserAttributes(UserAttributes.userAttributes.get());
    UserAttributes.userAttributes.set(null);
  }

  public Region getRealRegion() {
    return realRegion;
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.concurrent.ConcurrentMap#putIfAbsent(java.lang.Object, java.lang.Object)
   */
  @Override
  public Object putIfAbsent(Object key, Object value) {
    try {
      preOp();
      return this.realRegion.putIfAbsent(key, value);
    } finally {
      postOp();
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.concurrent.ConcurrentMap#remove(java.lang.Object, java.lang.Object)
   */
  @Override
  public boolean remove(Object key, Object value) {
    try {
      preOp();
      return this.realRegion.remove(key, value);
    } finally {
      postOp();
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.concurrent.ConcurrentMap#replace(java.lang.Object, java.lang.Object)
   */
  @Override
  public Object replace(Object key, Object value) {
    try {
      preOp();
      return this.realRegion.replace(key, value);
    } finally {
      postOp();
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.concurrent.ConcurrentMap#replace(java.lang.Object, java.lang.Object,
   * java.lang.Object)
   */
  @Override
  public boolean replace(Object key, Object oldValue, Object newValue) {
    try {
      preOp();
      return this.realRegion.replace(key, oldValue, newValue);
    } finally {
      postOp();
    }
  }

  @Override
  public RegionSnapshotService<?, ?> getSnapshotService() {
    return new RegionSnapshotServiceImpl(this);
  }

  @Override
  public void removeAll(Collection keys) {
    removeAll(keys, null);
  }

  @Override
  public void removeAll(Collection keys, Object aCallbackArgument) {
    try {
      preOp();
      this.realRegion.removeAll(keys, aCallbackArgument);
    } finally {
      postOp();
    }
  }
}
