/*
 * 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.tinkerpop.gremlin.process.traversal.step.util;

import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 */
public class MutablePath implements Path, Serializable {

    protected final List<Object> objects;
    protected final List<Set<String>> labels;

    protected MutablePath() {
        this(10);
    }

    private MutablePath(final int capacity) {
        this.objects = new ArrayList<>(capacity);
        this.labels = new ArrayList<>(capacity);
    }

    public static Path make() {
        return new MutablePath();
    }

    @Override
    @SuppressWarnings("CloneDoesntCallSuperClone,CloneDoesntDeclareCloneNotSupportedException")
    public MutablePath clone() {
        final MutablePath clone = new MutablePath(this.objects.size());
        // TODO: Why is this not working Hadoop serialization-wise?... Its cause DetachedPath's clone needs to detach on clone.
        /*final MutablePath clone = (MutablePath) super.clone();
        clone.objects = new ArrayList<>();
        clone.labels = new ArrayList<>();*/
        clone.objects.addAll(this.objects);
        for (final Set<String> labels : this.labels) {
            clone.labels.add(new LinkedHashSet<>(labels));
        }
        return clone;
    }

    @Override
    public boolean isEmpty() {
        return this.objects.isEmpty();
    }

    @Override
    public <A> A head() {
        return (A) this.objects.get(this.objects.size() - 1);
    }

    @Override
    public int size() {
        return this.objects.size();
    }

    @Override
    public Path extend(final Object object, final Set<String> labels) {
        this.objects.add(object);
        this.labels.add(new LinkedHashSet<>(labels));
        return this;
    }

    @Override
    public Path extend(final Set<String> labels) {
        if (!labels.isEmpty() && !this.labels.get(this.labels.size() - 1).containsAll(labels))
            this.labels.get(this.labels.size() - 1).addAll(labels);
        return this;
    }

    @Override
    public Path retract(final Set<String> removeLabels) {
        for (int i = this.labels.size() - 1; i >= 0; i--) {
            this.labels.get(i).removeAll(removeLabels);
            if (this.labels.get(i).isEmpty()) {
                this.labels.remove(i);
                this.objects.remove(i);
            }
        }
        return this;
    }

    @Override
    public <A> A get(int index) {
        return (A) this.objects.get(index);
    }

    @Override
    public <A> A get(final Pop pop, final String label) {
        if (Pop.mixed == pop) {
            return this.get(label);
        } else if (Pop.all == pop) {
            if (this.hasLabel(label)) {
                final Object object = this.get(label);
                if (object instanceof List)
                    return (A) object;
                else
                    return (A) Collections.singletonList(object);
            } else {
                return (A) Collections.emptyList();
            }
        } else {
            // Override default to avoid building temporary list, and to stop looking when we find the label.
            if (Pop.last == pop) {
                for (int i = this.labels.size() - 1; i >= 0; i--) {
                    if (labels.get(i).contains(label))
                        return (A) objects.get(i);
                }
            } else {
                for (int i = 0; i != this.labels.size(); i++) {
                    if (labels.get(i).contains(label))
                        return (A) objects.get(i);
                }
            }
            throw Path.Exceptions.stepWithProvidedLabelDoesNotExist(label);
        }
    }

    @Override
    public boolean hasLabel(final String label) {
        for (final Set<String> set : this.labels) {
            if (set.contains(label))
                return true;
        }
        return false;
    }

    @Override
    public List<Object> objects() {
        return Collections.unmodifiableList(this.objects);
    }

    @Override
    public List<Set<String>> labels() {
        return Collections.unmodifiableList(this.labels);
    }

    @Override
    public Iterator<Object> iterator() {
        return this.objects.iterator();
    }

    @Override
    public String toString() {
        return StringFactory.pathString(this);
    }

    @Override
    public int hashCode() {
        return this.objects.hashCode();
    }

    @Override
    public boolean equals(final Object other) {
        if (!(other instanceof Path))
            return false;
        final Path otherPath = (Path) other;
        if (otherPath.size() != this.objects.size())
            return false;

        final List<Object> otherPathObjects = otherPath.objects();
        final List<Set<String>> otherPathLabels = otherPath.labels();
        for (int i = this.objects.size() - 1; i >= 0; i--) {
            if (!this.objects.get(i).equals(otherPathObjects.get(i)))
                return false;
            if (!this.labels.get(i).equals(otherPathLabels.get(i)))
                return false;
        }
        return true;
    }
}
