/*
 * 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.logging.log4j.spi;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.logging.log4j.ThreadContext.ContextStack;
import org.apache.logging.log4j.util.StringBuilderFormattable;

/**
 * TODO
 */
public class MutableThreadContextStack implements ThreadContextStack, StringBuilderFormattable {

    private static final long serialVersionUID = 50505011L;

    /**
     * The underlying list (never null).
     */
    private final List<String> list;
    private boolean frozen;

    /**
     * Constructs an empty MutableThreadContextStack.
     */
    public MutableThreadContextStack() {
        this(new ArrayList<String>());
    }

    /**
     * Constructs a new instance.
     * @param list
     */
    public MutableThreadContextStack(final List<String> list) {
        this.list = new ArrayList<>(list);
    }

    private MutableThreadContextStack(final MutableThreadContextStack stack) {
        this.list = new ArrayList<>(stack.list);
    }

    private void checkInvariants() {
        if (frozen) {
            throw new UnsupportedOperationException("context stack has been frozen");
        }
    }

    @Override
    public String pop() {
        checkInvariants();
        if (list.isEmpty()) {
            return null;
        }
        final int last = list.size() - 1;
        final String result = list.remove(last);
        return result;
    }

    @Override
    public String peek() {
        if (list.isEmpty()) {
            return null;
        }
        final int last = list.size() - 1;
        return list.get(last);
    }

    @Override
    public void push(final String message) {
        checkInvariants();
        list.add(message);
    }

    @Override
    public int getDepth() {
        return list.size();
    }

    @Override
    public List<String> asList() {
        return list;
    }

    @Override
    public void trim(final int depth) {
        checkInvariants();
        if (depth < 0) {
            throw new IllegalArgumentException("Maximum stack depth cannot be negative");
        }
        if (list == null) {
            return;
        }
        final List<String> copy = new ArrayList<>(list.size());
        final int count = Math.min(depth, list.size());
        for (int i = 0; i < count; i++) {
            copy.add(list.get(i));
        }
        list.clear();
        list.addAll(copy);
    }

    @Override
    public ThreadContextStack copy() {
        return new MutableThreadContextStack(this);
    }

    @Override
    public void clear() {
        checkInvariants();
        list.clear();
    }

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

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

    @Override
    public boolean contains(final Object o) {
        return list.contains(o);
    }

    @Override
    public Iterator<String> iterator() {
        return list.iterator();
    }

    @Override
    public Object[] toArray() {
        return list.toArray();
    }

    @Override
    public <T> T[] toArray(final T[] ts) {
        return list.toArray(ts);
    }

    @Override
    public boolean add(final String s) {
        checkInvariants();
        return list.add(s);
    }

    @Override
    public boolean remove(final Object o) {
        checkInvariants();
        return list.remove(o);
    }

    @Override
    public boolean containsAll(final Collection<?> objects) {
        return list.containsAll(objects);
    }

    @Override
    public boolean addAll(final Collection<? extends String> strings) {
        checkInvariants();
        return list.addAll(strings);
    }

    @Override
    public boolean removeAll(final Collection<?> objects) {
        checkInvariants();
        return list.removeAll(objects);
    }

    @Override
    public boolean retainAll(final Collection<?> objects) {
        checkInvariants();
        return list.retainAll(objects);
    }

    @Override
    public String toString() {
        return String.valueOf(list);
    }

    @Override
    public void formatTo(final StringBuilder buffer) {
        buffer.append('[');
        for (int i = 0; i < list.size(); i++) {
            if (i > 0) {
                buffer.append(',').append(' ');
            }
            buffer.append(list.get(i));
        }
        buffer.append(']');
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((this.list == null) ? 0 : this.list.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof ThreadContextStack)) {
            return false;
        }
        final ThreadContextStack other = (ThreadContextStack) obj;
        final List<String> otherAsList = other.asList();
        if (this.list == null) {
            if (otherAsList != null) {
                return false;
            }
        } else if (!this.list.equals(otherAsList)) {
            return false;
        }
        return true;
    }

    @Override
    public ContextStack getImmutableStackOrNull() {
        return copy();
    }

    /**
     * "Freezes" this context stack so it becomes immutable: all mutator methods will throw an exception from now on.
     */
    public void freeze() {
        frozen = true;
    }

    /**
     * Returns whether this context stack is frozen.
     * @return whether this context stack is frozen.
     */
    public boolean isFrozen() {
        return frozen;
    }
}
