// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed 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 com.google.devtools.build.lib.bazel.repository;

import static com.google.devtools.build.lib.bazel.repository.StripPrefixedPath.maybeDeprefixSymlink;

import com.google.common.base.Optional;
import com.google.common.io.ByteStreams;
import com.google.devtools.build.lib.bazel.repository.DecompressorValue.Decompressor;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;

/**
 * Common code for unarchiving a compressed TAR file.
 */
public abstract class CompressedTarFunction implements Decompressor {
  protected abstract InputStream getDecompressorStream(DecompressorDescriptor descriptor)
      throws IOException;

  @Override
  public Path decompress(DecompressorDescriptor descriptor)
      throws InterruptedException, IOException {
    if (Thread.interrupted()) {
      throw new InterruptedException();
    }
    Optional<String> prefix = descriptor.prefix();
    Map<String, String> renameFiles = descriptor.renameFiles();
    boolean foundPrefix = false;
    Set<String> availablePrefixes = new HashSet<>();
    // Store link, target info of symlinks, we create them after regular files are extracted.
    Map<Path, PathFragment> symlinks = new HashMap<>();

    try (InputStream decompressorStream = getDecompressorStream(descriptor)) {
      TarArchiveInputStream tarStream = new TarArchiveInputStream(decompressorStream);
      TarArchiveEntry entry;
      while ((entry = tarStream.getNextTarEntry()) != null) {
        String entryName = entry.getName();
        entryName = renameFiles.getOrDefault(entryName, entryName);
        StripPrefixedPath entryPath = StripPrefixedPath.maybeDeprefix(entryName, prefix);
        foundPrefix = foundPrefix || entryPath.foundPrefix();

        if (prefix.isPresent() && !foundPrefix) {
          Optional<String> suggestion =
              CouldNotFindPrefixException.maybeMakePrefixSuggestion(entryPath.getPathFragment());
          if (suggestion.isPresent()) {
            availablePrefixes.add(suggestion.get());
          }
        }

        if (entryPath.skip()) {
          continue;
        }

        Path filePath = descriptor.destinationPath().getRelative(entryPath.getPathFragment());
        filePath.getParentDirectory().createDirectoryAndParents();
        if (entry.isDirectory()) {
          filePath.createDirectoryAndParents();
        } else {
          if (entry.isSymbolicLink() || entry.isLink()) {
            PathFragment targetName = PathFragment.create(entry.getLinkName());
            targetName = maybeDeprefixSymlink(targetName, prefix, descriptor.destinationPath());
            if (entry.isSymbolicLink()) {
              symlinks.put(filePath, targetName);
            } else {
              Path targetPath = descriptor.destinationPath().getRelative(targetName);
              if (filePath.equals(targetPath)) {
                // The behavior here is semantically different, depending on whether the underlying
                // filesystem is case-sensitive or case-insensitive. However, it is effectively the
                // same: we drop the link entry.
                // * On a case-sensitive filesystem, this is a hardlink to itself, such as GNU tar
                //   creates when given repeated files. We do nothing since the link already exists.
                // * On a case-insensitive filesystem, we may be extracting a differently-cased
                //   hardlink to the same file (such as when extracting an archive created on a
                //   case-sensitive filesystem). GNU tar, for example, will drop the new link entry.
                //   BSD tar on MacOS X (by default case-insensitive) errors and aborts extraction.
              } else {
                if (filePath.exists()) {
                  filePath.delete();
                }
                FileSystemUtils.createHardLink(filePath, targetPath);
              }
            }
          } else {
            try (OutputStream out = filePath.getOutputStream()) {
              ByteStreams.copy(tarStream, out);
            }
            filePath.chmod(entry.getMode());

            // This can only be done on real files, not links, or it will skip the reader to
            // the next "real" file to try to find the mod time info.
            Date lastModified = entry.getLastModifiedDate();
            filePath.setLastModifiedTime(lastModified.getTime());
          }
        }
        if (Thread.interrupted()) {
          throw new InterruptedException();
        }
      }

      for (Map.Entry<Path, PathFragment> symlink : symlinks.entrySet()) {
        Path linkPath = symlink.getKey();
        if (linkPath.exists()) {
          linkPath.delete();
        }
        FileSystemUtils.ensureSymbolicLink(linkPath, symlink.getValue());
      }

      if (prefix.isPresent() && !foundPrefix) {
        throw new CouldNotFindPrefixException(prefix.get(), availablePrefixes);
      }
    }

    return descriptor.destinationPath();
  }
}
