// 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();

      Manifest includedManifest;
      Path includedPath;
      Iterator<Include> i = manifest.getInclude().listIterator();
      String include;
      while (i.hasNext()) {
        include = i.next().getName();
        includedPath = Paths.get(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);
    }
  }
}
