/*
 * 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.sentry.hdfs;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import com.google.common.annotations.VisibleForTesting;
import org.apache.sentry.hdfs.service.thrift.TPathChanges;
import org.apache.sentry.hdfs.service.thrift.TPathsUpdate;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.conf.Configuration;
import org.apache.http.client.utils.URIBuilder;

import org.apache.thrift.TException;

import static org.apache.sentry.hdfs.service.thrift.sentry_hdfs_serviceConstants.UNUSED_PATH_UPDATE_IMG_NUM;

/**
 * A wrapper class over the TPathsUpdate thrift generated class. Please see
 * {@link Updateable.Update} for more information
 */
public class PathsUpdate implements Updateable.Update {

  public static final String ALL_PATHS = "__ALL_PATHS__";


  private static final Configuration CONF = new Configuration();
  private static String DEFAULT_SCHEME = FileSystem.getDefaultUri(CONF).getScheme();
  private static final String SUPPORTED_SCHEME = "hdfs";

  private final TPathsUpdate tPathsUpdate;

  public PathsUpdate() {
    this(0, false);
  }

  public PathsUpdate(TPathsUpdate tPathsUpdate) {
    this.tPathsUpdate = tPathsUpdate;
  }

  public PathsUpdate(long seqNum, boolean hasFullImage) {
    this(seqNum, UNUSED_PATH_UPDATE_IMG_NUM, hasFullImage);
  }

  public PathsUpdate(long seqNum, long imgNum, boolean hasFullImage) {
    tPathsUpdate = new TPathsUpdate(hasFullImage, seqNum, new ArrayList<TPathChanges>());
    tPathsUpdate.setImgNum(imgNum);
  }

  @Override
  public boolean hasFullImage() {
    return tPathsUpdate.isHasFullImage();
  }

  public TPathChanges newPathChange(String authzObject) {

    TPathChanges pathChanges = new TPathChanges(authzObject,
        new ArrayList<List<String>>(), new ArrayList<List<String>>());
    tPathsUpdate.addToPathChanges(pathChanges);
    return pathChanges;
  }

  List<TPathChanges> getPathChanges() {
    return tPathsUpdate.getPathChanges();
  }

  @Override
  public long getSeqNum() {
    return tPathsUpdate.getSeqNum();
  }

  @Override
  public void setSeqNum(long seqNum) {
    tPathsUpdate.setSeqNum(seqNum);
  }

  @Override
  public long getImgNum() {
    return tPathsUpdate.getImgNum();
  }

  @Override
  public void setImgNum(long imgNum) {
    tPathsUpdate.setImgNum(imgNum);
  }

  public TPathsUpdate toThrift() {
    return tPathsUpdate;
  }

  /**
   * Only used for testing.
   * @param scheme new default scheme
   */
  @VisibleForTesting
  public static void setDefaultScheme(String scheme) {
    DEFAULT_SCHEME = scheme;
  }

  /**
   * Convert URI to path, trimming leading slash.
   * @param path HDFS location in one of the forms:
   * <ul>
   *   <li>hdfs://hostname:port/path
   *   <li>hdfs:///path
   *   <li>/path, in which case, scheme will be constructed from FileSystem.getDefaultURI
   *   <li>URIs with non hdfs schemee will just be ignored
   * </ul>
   * @return Path with scheme/ authority stripped off.
   * Returns null if a non HDFS path or if path is null/empty.
   */
  public static String parsePath(String path) throws SentryMalformedPathException {
    if (StringUtils.isEmpty(path)) {
      return null;
    }

    URI uri;
    try {
      // Below converts unescaped path to escaped string and the constructs a URI from it.
      uri = new URI(StringUtils.stripStart(new URIBuilder().setPath(path).toString(), "/"));
    } catch (URISyntaxException e) {
      throw new SentryMalformedPathException("Incomprehensible path [" + path + "]", e);
    }

    String scheme = uri.getScheme();
    if (scheme == null) {
      scheme = DEFAULT_SCHEME;
      if(scheme == null) {
        throw new SentryMalformedPathException(
                "Scheme is missing and could not be constructed from configuration");
      }
    }

    // Non-HDFS paths are skipped.
    if(!scheme.equalsIgnoreCase(SUPPORTED_SCHEME)) {
      return null;
    }

    String uriPath = uri.getPath();
    if(uriPath == null) {
      throw new SentryMalformedPathException("Path is empty. uri=" + uri);
    }
    if (!uriPath.startsWith("/")) {
      throw new SentryMalformedPathException("Path part of uri does not seem right, was expecting a non empty path" +
              ": path = " + uriPath + ", uri=" + uri);
    }
    // Reduce multiple consecutive forward slashes to one.
    // It's probably a rare case, so use indexOf() before expensive regex.
    if (uriPath.indexOf("//") >= 0) {
      uriPath = uriPath.replaceAll("//*", "/");
    }
    // Remove leading and trailing slashes
    return StringUtils.strip(uriPath, "/");
  }

  @Override
  public byte[] serialize() throws IOException {
    return ThriftSerializer.serialize(tPathsUpdate);
  }

  @Override
  public void deserialize(byte[] data) throws IOException {
    ThriftSerializer.deserialize(tPathsUpdate, data);
  }

  @Override
  public void JSONDeserialize(String update) throws TException {
    ThriftSerializer.deserializeFromJSON(tPathsUpdate, update);
  }

  @Override
  public String JSONSerialize() throws TException {
    return ThriftSerializer.serializeToJSON(tPathsUpdate);
  }

  @Override
  public int hashCode() {
    return (tPathsUpdate == null) ? 0 : tPathsUpdate.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == null) {
      return false;
    }

    if (this == obj) {
      return true;
    }

    if (getClass() != obj.getClass()) {
      return false;
    }

    PathsUpdate other = (PathsUpdate) obj;
    if (tPathsUpdate == null) {
      return other.tPathsUpdate == null;
    }
    return tPathsUpdate.equals(other.tPathsUpdate);
  }

  @Override
  public String toString() {
    // TPathsUpdate implements toString() perfectly; null tPathsUpdate is ok
    return getClass().getSimpleName() + "(" + tPathsUpdate + ")";
  }

}
