// Copyright (C) 2015 Advanced Micro Devices, Inc.  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.amd.gerrit.plugins.manifestsubscription;

import com.amd.gerrit.plugins.manifestsubscription.manifest.Include;
import com.amd.gerrit.plugins.manifestsubscription.manifest.Manifest;
import com.amd.gerrit.plugins.manifestsubscription.manifest.Project;
import com.amd.gerrit.plugins.manifestsubscription.manifest.RemoveProject;
import com.google.common.collect.Sets;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class CanonicalManifest {
  private Map<String, Manifest> manifests;

  public CanonicalManifest(VersionedManifests manifests) {
    this.manifests = manifests.getManifests();
  }

  public CanonicalManifest(Map<String, Manifest> manifests) {
    this.manifests = manifests;
  }

  Manifest getCanonicalManifest(String path) throws ManifestReadException {
    if (manifests.containsKey(path)) {
      Manifest manifest = (Manifest) manifests.get(path).clone();
      Path manifestPath = Paths.get(path);


      Manifest includedManifest;
      Path includedPath;
      Iterator<Include> i = manifest.getInclude().listIterator();
      String include;
      String parent;
      while (i.hasNext()) {
        parent = manifestPath.getParent() != null ? manifestPath.getParent().toString() + "/" : "";
        include = i.next().getName();
        includedPath = Paths.get(parent+include);
        i.remove();

        includedManifest = getCanonicalManifest(includedPath.normalize().toString());

        try {
          mergeManifestInto(includedManifest, manifest);
        } catch (Exception e) {
          throw new ManifestReadException(path);
        }

      }
      // Clear remove project after all include manifest is processed
      manifest.getRemoveProject().clear();

      return manifest;
    }

    throw new ManifestReadException(path);
  }

  private Manifest mergeManifestInto(Manifest inner, Manifest outer)
      throws Exception {
    if (outer.getDefault() != null && inner.getDefault() != null) {
      throw new Exception();
    }
    if (outer.getNotice() != null && inner.getNotice() != null) {
      throw new Exception();
    }
    if (outer.getManifestServer() != null && inner.getManifestServer() != null) {
      throw new Exception();
    }
    if (outer.getRepoHooks() != null && inner.getRepoHooks() != null) {
      throw new Exception();
    }

    //TODO add more check
    resolveRemoveProject(inner, outer);

    if (outer.getDefault() == null) {
      outer.setDefault(inner.getDefault());
    }
    if (outer.getNotice() == null) {
      outer.setNotice(inner.getNotice());
    }
    if (outer.getManifestServer() == null) {
      outer.setManifestServer(inner.getManifestServer());
    }
    if (outer.getRepoHooks() == null) {
      outer.setRepoHooks(inner.getRepoHooks());
    }


    //TODO name remote name duplication check
    outer.getRemote().addAll(inner.getRemote());

    outer.getProject().addAll(inner.getProject());
    outer.getExtendProject().addAll(inner.getExtendProject());

    return outer;
  }

  private void resolveRemoveProject(Manifest manifest, Set<String> toBeRemoved) {
    Project p;
    Iterator<Project> i = manifest.getProject().listIterator();
    while (i.hasNext()) {
      p = i.next();

      if (toBeRemoved.contains(p.getName())) {
        i.remove();
      }
    }
  }

  private void resolveRemoveProject(Manifest manifest, Manifest toRemove) {
    Set<String> removeProjects = Sets.newHashSet();

    RemoveProject rp;
    Iterator<RemoveProject> i = toRemove.getRemoveProject().listIterator();
    while (i.hasNext()) {
      rp = i.next();
      removeProjects.add(rp.getName());
    }

    if (removeProjects.size() > 0) {
      resolveRemoveProject(manifest, removeProjects);
    }
  }
}
