// Copyright (C) 2015 The Android Open Source Project
//
// 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.googlesource.gerrit.plugins.importer;

import static java.lang.String.format;

import com.google.gerrit.extensions.annotations.PluginData;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.AcceptsCreate;
import com.google.gerrit.extensions.restapi.ChildCollection;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.ConfigResource;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;

@Singleton
@RequiresCapability(ImportCapability.ID)
public class ProjectsCollection
    implements ChildCollection<ConfigResource, ImportProjectResource>,
        AcceptsCreate<ConfigResource> {

  class FileSystemLayout {

    private String SUFFIX_IMPORT_STATUS_FILE = ".$importstatus";

    public File getLockRoot() {
      return lockRoot;
    }

    File getImportStatusFile(String id) {
      return new File(lockRoot, format("%s%s", id, SUFFIX_IMPORT_STATUS_FILE));
    }

    String resolveProjectName(File f) throws IOException {
      if (!f.isFile()) {
        throw new RuntimeException(
            format(
                "'%s' is not a file. Project names"
                    + "can only be resolved for existing files, not for directories.",
                f));
      }

      if (!f.getName().endsWith(SUFFIX_IMPORT_STATUS_FILE)) {
        throw new RuntimeException(
            format(
                "'%s' is not a valid import status" + "file. Invalid appendix. Should be '%s'.",
                f, SUFFIX_IMPORT_STATUS_FILE));
      }
      String diff = diff(lockRoot, f);
      return diff.substring(0, diff.length() - SUFFIX_IMPORT_STATUS_FILE.length());
    }

    /**
     * Returns the path between two file instances. The child instance is expected to be a child of
     * the parent instance.
     *
     * @param parent
     * @param child
     * @return The path between parent and child.
     * @throws IOException in case <code>child</code> is not a child of <code>parent</code>.
     */
    private String diff(File parent, File child) throws IOException {
      Path parentPath = parent.getAbsoluteFile().toPath();
      Path childPath = child.getAbsoluteFile().toPath();
      if (childPath.startsWith(parentPath)) {
        return parentPath.relativize(childPath).toString();
      }
      throw new IOException(String.format("'%s' is not a child of '%s'.", child, parent));
    }
  }

  public final FileSystemLayout FS_LAYOUT = new FileSystemLayout();

  private final DynamicMap<RestView<ImportProjectResource>> views;
  private final ImportProject.Factory importProjectFactory;
  private final Provider<ListImportedProjects> list;
  private final File lockRoot;

  @Inject
  ProjectsCollection(
      DynamicMap<RestView<ImportProjectResource>> views,
      ImportProject.Factory importProjectFactory,
      Provider<ListImportedProjects> list,
      @PluginData File data) {
    this.views = views;
    this.importProjectFactory = importProjectFactory;
    this.list = list;
    this.lockRoot = data;
  }

  @Override
  public RestView<ConfigResource> list() {
    return list.get();
  }

  @Override
  public ImportProjectResource parse(ConfigResource parent, IdString id)
      throws ResourceNotFoundException {
    return parse(id.get());
  }

  public ImportProjectResource parse(String id) throws ResourceNotFoundException {
    File f = FS_LAYOUT.getImportStatusFile(id);
    if (!f.exists()) {
      throw new ResourceNotFoundException(id);
    }

    return new ImportProjectResource(id, f);
  }

  @Override
  public DynamicMap<RestView<ImportProjectResource>> views() {
    return views;
  }

  @Override
  @SuppressWarnings("unchecked")
  public ImportProject create(ConfigResource parent, IdString id) throws RestApiException {
    return importProjectFactory.create(new Project.NameKey(id.get()));
  }
}
