/*
 * 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.
 */

/* $Rev$ $Date$ */

#ifndef tuscany_list_hpp
#define tuscany_list_hpp

/**
 * Simple list functions.
 */

#include <assert.h>
#include "string.hpp"
#include "fstream.hpp"
#include "function.hpp"

namespace tuscany {

#ifdef WANT_MAINTAINER_COUNTERS

/**
 * Debug utilities. Counters used to track instances of lists.
 */
long countLists = 0;
long countILists = 0;
long countCLists = 0;
long countELists = 0;

inline const bool resetListCounters() noexcept {
    countLists = countILists = countCLists = countELists = 0;
    return true;
}

inline const bool checkListCounters() noexcept {
    return countLists == 0;
}

inline const bool printListCounters() noexcept {
    cout << "countLists " << countLists << endl;
    cout << "countELists " << countELists << endl;
    cout << "countILists " << countILists << endl;
    cout << "countCLists " << countCLists << endl;
    return true;
}

#else

#define resetListCounters()
#define checkListCounters() true
#define printListCounters()

#endif

#ifdef WANT_MAINTAINER_WATCH

/**
 * Debug utilities. Macro used to write the contents of a list to
 * a string, easier to watch in a debugger than the list itself.
 */
#define debug_watchList() do { \
        this->watch = watchList(*this); \
    } while (0)

#else

#define debug_watchList();

#endif

/**
 * A car/cdr lisp-like pair, base structure to construct lists.
 */

template<typename T> class list {
public:

    inline list() noexcept : car() {
        debug_inc(countLists);
        debug_inc(countELists);
        debug_watchList();
    }

    inline list(const T& car, const lambda<list<T>()>& cdr) noexcept : car(car), cdr(cdr) {
        debug_inc(countLists);
        debug_inc(countILists);
        debug_watchList();
    }

    inline list(const list& p) noexcept : car(p.car), cdr(p.cdr) {
        debug_inc(countLists);
        debug_inc(countCLists);
#ifdef WANT_MAINTAINER_WATCH
        watch = p.watch;
#endif
    }

    list<T>& operator=(const list<T>& p) = delete;

    inline ~list() noexcept {
        debug_dec(countLists);
    }

    inline const bool operator==(const list<T>& p) const noexcept {
        if(this == &p)
            return true;
        if(isNil(cdr))
            return isNil(p.cdr);
        if(isNil(p.cdr))
            return false;
        if(!(car == p.car))
            return false;
        if(cdr == p.cdr)
            return true;
        return cdr() == p.cdr();
    }

    inline const bool operator<(const list<T>& p) const noexcept {
        if(this == &p)
            return false;
        if (isNil(cdr))
            return !isNil(p.cdr);
        if (isNil(p.cdr))
            return false;
        if (car < p.car)
            return true;
        if (car != p.car)
            return false;
        return cdr() < p.cdr();
    }

    inline const bool operator>(const list<T>& p) const noexcept {
        if(this == &p)
            return false;
        if (isNil(cdr))
            return false;
        if (isNil(p.cdr))
            return true;
        if (car > p.car)
            return true;
        if (car != p.car)
            return false;
        return cdr() > p.cdr();
    }

    inline const bool operator!=(const list<T>& p) const noexcept {
        return !this->operator==(p);
    }

    inline operator const list<list<T> >() const noexcept {
        return (list<list<T> >)T(*this);
    }

private:
#ifdef WANT_MAINTAINER_WATCH
    template<typename X> friend const string watchList(const list<X>& p) noexcept;
    string watch;
#endif

    template<typename X> friend const bool isNil(const list<X>& p) noexcept;
    template<typename X> friend const X car(const list<X>& p) noexcept;
    template<typename X> friend const list<X> cdr(const list<X>& p) noexcept;

    const T car;
    const lambda<list<T>()> cdr;
};

#ifdef WANT_MAINTAINER_WATCH

/**
 * Debug utility used to write the contents of a list to a string, easier
 * to watch than the list itself in a debugger.
 */
template<typename T> inline const string watchList(const list<T>& p) noexcept {
    if(isNil(p))
        return "()";
    odebugstream os;
    os << "(" << car(p) << " ...)";
    return str(os);
}

#endif

/**
 * Returns true if the given list is nil.
 */
template<typename T> inline const bool isNil(const list<T>& p) noexcept {
    return isNil(p.cdr);
}

/**
 * Write a list to an output stream.
 */
template<typename T> inline ostream& writeHelper(ostream& out, const list<T>& l) noexcept {
    if (isNil(l))
        return out;
    out << " " << car(l);
    return writeHelper(out, cdr(l));
}

template<typename T> inline ostream& operator<<(ostream& out, const list<T>& l) noexcept {
    if(isNil(l))
        return out << "()";
    out << "(" << car(l);
    writeHelper<T>(out, cdr(l));
    return out << ")";
}

/**
 * Construct a (lazy) list from a value and a lambda function that returns the cdr.
 */
template<typename T> inline const list<T> cons(const T& car, const lambda<const list<T>()>& cdr) noexcept {
    return list<T> (car, cdr);
}

/**
 * Construct a list from a value and a cdr list.
 */
template<typename T> inline const list<T> cons(const T& car, const list<T>& cdr) noexcept {
    return list<T> (car, result(cdr));
}

/**
 * Cons variations for use with the reduce and reduceRight functions.
 */
template<typename T> inline const list<T> lcons(const list<T>& cdr, const T& car) noexcept {
    return cons<T>(car, cdr);
}

template<typename T> inline const list<T> rcons(const T& car, const list<T>& cdr) noexcept {
    return cons<T>(car, cdr);
}

/**
 * Construct a list of one value.
 */
template<typename T> inline const list<T> mklist(const T& car) noexcept {
    return list<T> (car, result(list<T> ()));
}

/**
 * Construct a list of two values.
 */
template<typename T> inline const list<T> mklist(const T& a, const T& b) noexcept {
    return cons(a, mklist(b));
}

/**
 * Construct a list of three values.
 */
template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c) noexcept {
    return cons(a, cons(b, mklist(c)));
}

/**
 * Construct a list of four values.
 */
template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d) noexcept {
    return cons(a, cons(b, cons(c, mklist(d))));
}

/**
 * Construct a list of five values.
 */
template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e) noexcept {
    return cons(a, cons(b, cons(c, cons(d, mklist(e)))));
}

/**
 * Construct a list of six values.
 */
template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) noexcept {
    return cons(a, cons(b, cons(c, cons(d, cons(e, mklist(f))))));
}

/**
 * Returns the car of a list.
 */
template<typename T> inline const T car(const list<T>& p) noexcept {
    // Abort if trying to access the car of a nil list
    assertOrFail(!isNil(p.cdr));
    return p.car;
}

/**
 * Returns the cdr of a list.
 */
template<typename T> inline const list<T> cdr(const list<T>& p) noexcept {
    return p.cdr();
}

/**
 * Returns the car of the cdr (the 2nd element) of a list.
 */
template<typename T> inline const T cadr(const list<T>& p) noexcept {
    return car(cdr(p));
}

/**
 * Returns the 3rd element of a list.
 */
template<typename T> inline const T caddr(const list<T>& p) noexcept {
    return car(cdr(cdr(p)));
}

/**
 * Returns the 4th element of a list.
 */
template<typename T> inline const T cadddr(const list<T>& p) noexcept {
    return car(cdr(cdr(cdr(p))));
}

/**
 * Returns the 5th element of a list.
 */
template<typename T> inline const T caddddr(const list<T>& p) noexcept {
    return car(cdr(cdr(cdr(cdr(p)))));
}

/**
 * Returns the 6th element of a list.
 */
template<typename T> inline const T cadddddr(const list<T>& p) noexcept {
    return car(cdr(cdr(cdr(cdr(cdr(p))))));
}

/**
 * Returns the 7th element of a list.
 */
template<typename T> inline const T caddddddr(const list<T>& p) noexcept {
    return car(cdr(cdr(cdr(cdr(cdr(cdr(p)))))));
}

/**
 * Returns the 8th element of a list.
 */
template<typename T> inline const T cadddddddr(const list<T>& p) noexcept {
    return car(cdr(cdr(cdr(cdr(cdr(cdr(cdr(p))))))));
}

/**
 * Returns a list of elements from the 3rd to the end of a list.
 */
template<typename T> inline const list<T> cddr(const list<T>& p) noexcept {
    return cdr(cdr(p));
}

/**
 * Returns a list of elements from the 4th to the end of a list.
 */
template<typename T> inline const list<T> cdddr(const list<T>& p) noexcept {
    return cdr(cdr(cdr(p)));
}

/**
 * Returns a list of elements from the 5th to the end of a list.
 */
template<typename T> inline const list<T> cddddr(const list<T>& p) noexcept {
    return cdr(cdr(cdr(cdr(p))));
}

/**
 * Returns a list of elements from the 6th to the end of a list.
 */
template<typename T> inline const list<T> cdddddr(const list<T>& p) noexcept {
    return cdr(cdr(cdr(cdr(cdr(p)))));
}

/**
 * Returns a list of elements from the 7th to the end of a list.
 */
template<typename T> inline const list<T> cddddddr(const list<T>& p) noexcept {
    return cdr(cdr(cdr(cdr(cdr(cdr(p))))));
}

/**
 * Returns a list of elements from the 8th to the end of a list.
 */
template<typename T> inline const list<T> cdddddddr(const list<T>& p) noexcept {
    return cdr(cdr(cdr(cdr(cdr(cdr(cdr(p)))))));
}

/**
 * Returns the length of a list.
 */
template<typename T> inline const size_t length(const list<T>& p) noexcept {
    const lambda<size_t(const size_t, const list<T>&)> lengthRef = [&lengthRef](const size_t c, const list<T>& p) -> const size_t {
        if(isNil(p))
            return c;
        return lengthRef(c + 1, cdr(p));
    };
    return lengthRef(0, p);
}

/**
 * Appends a list and a lambda function returning a list.
 */
template<typename T> inline const list<T> append(const list<T>&a, const lambda<const list<T>()>& fb) noexcept {
    if(isNil(a))
        return fb();
    return cons<T>(car(a), [a, fb]() { return append(cdr(a), fb); });
}

/**
 * Appends two lists.
 */
template<typename T> inline const list<T> append(const list<T>&a, const list<T>& b) noexcept {
    return append(a, result(b));
}

/**
 * Append a value to a list.
 */
template<typename T> inline const list<T> operator+(const list<T>& l, const T& v) noexcept {
    return append(l, mklist(v));
}

template<typename T, typename V> const list<T> inline operator+(const list<T>& l, const V& v) noexcept {
    return append(l, mklist<T>(v));
}

/**
 * Run a map lambda function on a list.
 */
template<typename T, typename R> inline const list<R> map(const lambda<const R(const T)>& f, const list<T>& p) noexcept {
    if(isNil(p))
        return list<R> ();
    return cons(f(car(p)), map(f, cdr(p)));
}

/**
 * Run a reduce lambda function on a list.
 */
template<typename T, typename R> inline const R reduce(const lambda<const R(const R, const T)>& f, const R& initial, const list<T>& p) noexcept {
    const lambda<const R(const R&, const list<T>&p)> reduceAccumulate = [f, &reduceAccumulate](const R& acc, const list<T>& p) -> R {
        if(isNil(p))
            return acc;
        return reduceAccumulate(f(acc, car(p)), cdr(p));
    };
    return reduceAccumulate(initial, p);
}

template<typename T, typename R> inline const R reduceRight(const lambda<const R(const T, const R)>& f, const R& initial, const list<T>& p) noexcept {
    const lambda<const R(const list<T>&p, const R&)> reduceRightAccumulate = [f, &reduceRightAccumulate](const list<T>& p, const R& acc) -> R {
        if(isNil(p))
            return acc;
        return reduceRightAccumulate(cdr(p), f(car(p), acc));
    };
    return reduceRightAccumulate(p, initial);
}

/**
 * Run a filter lambda function on a list.
 */
template<typename T> inline const list<T> filter(const lambda<const bool(const T)>& f, const list<T>& p) noexcept {
    if(isNil(p))
        return list<T> ();
    if(f(car(p))) {
        const lambda<const list<T>(const lambda<const bool(const T)>, const list<T>)> ff(filter<T>);
        return cons(car(p), curry(ff, f, cdr(p)));
    }
    return filter(f, cdr(p));
}

/**
 * Returns a list pointing to a member of a list.
 */
template<typename T> inline const list<T> member(const T& t, const list<T>& p) noexcept {
    if(isNil(p))
        return list<T> ();
    if(t == car(p))
        return p;
    return member(t, cdr(p));
}

/**
 * Reverse a list.
 */
template<typename T> inline const list<T> reverseIter(const list<T>& acc, const list<T>& p) noexcept {
    if(isNil(p))
        return acc;
    return reverseIter(cons(car(p), acc), cdr(p));
}

template<typename T> inline const list<T> reverse(const list<T>& p) noexcept {
    return reverseIter(list<T> (), p);
}

/**
 * Returns a sequence of values between the given bounds.
 */
template<typename T> inline const list<T> seq(const T& start, const T& end) noexcept {
    if(start == end)
        return mklist(start);
    if(start < end)
        return cons<T>(start, [start, end] { return seq<T> (start + 1, end); });
    return cons<T>(start, [start, end] { return seq<T> (start - 1, end); });
}

/**
 * Returns the i-th element of a list.
 */
template<typename T> inline const T listRef(const list<T>& l, const size_t i) noexcept {
    if(i == 0)
        return car(l);
    return listRef(cdr(l), i - 1);
}

/**
 * Returns the tail of a list, ommiting the first k elements.
 */
template<typename T> inline const list<T> listTail(const list<T>& l, const size_t k) noexcept {
    if(k == 0)
        return l;
    if(isNil(l))
        return l;
    return listTail(cdr(l), k - 1);
}

/**
 * Substitute elements in a list.
 */
template<typename T> inline const list<T> subst(const T& o, const T& n, const list<T>& p) noexcept {
    if(isNil(p))
        return p;
    if(o == car(p))
        return cons<T>(n, subst(o, n, cdr(p)));
    return cons<T>(car(p), subst(o, n, cdr(p)));
}

/**
 * Returns the first pair matching a key from a list of key value pairs.
 */
template<typename T> inline const list<T> assoc(const T& k, const list<list<T> >& p) noexcept {
    if(isNil(p))
        return list<T>();
    if(k == car(car(p)))
        return car(p);
    return assoc(k, cdr(p));
}

/**
 * Returns the first pair matching a key from a list of key value pairs.
 * Requires T to support isList and cast to list<T>.
 */
template<typename T> inline const list<T> assoc(const T& k, const list<T>& p) noexcept {
    if(isNil(p))
        return list<T>();
    const T c = car(p);
    if(isList(c) && k == car<T>(c))
        return c;
    return assoc(k, cdr(p));
}

/**
 * Returns a list of lists containing elements from two input lists.
 */
template<typename T> inline const list<list<T> > zip(const list<T>& a, const list<T>& b) noexcept {
    if (isNil(a) || isNil(b))
        return list<list<T> >();
    return cons<list<T> >(mklist<T>(car(a), car(b)), zip(cdr(a), cdr(b)));
}

/**
 * Converts a list of key value pairs to a list containing the list of keys and the list of values.
 */
template<typename T> inline const list<T> unzipKeys(const list<list<T> >& l) noexcept {
    if (isNil(l))
        return list<T>();
    return cons(car(car(l)), unzipKeys(cdr(l)));
}

template<typename T> inline const list<T> unzipValues(const list<list<T> >& l) noexcept {
    if (isNil(l))
        return list<T>();
    return cons(cadr(car(l)), unzipValues(cdr(l)));
}

template<typename T> inline const list<list<T> > unzip(const list<list<T> >& l) noexcept {
    return mklist<list<T> >(unzipKeys(l), unzipValues(l));
}

/**
 * Delete assocs matching a key from a list of assocs.
 */
template<typename T> inline const list<list<T> > delAssoc(const T& k, const list<list<T> >& p) noexcept {
    if(isNil(p))
        return p;
    if(k == car(car(p)))
        return delAssoc(k, cdr(p));
    return cons<list<T> >(car(p), delAssoc(k, cdr(p)));
}

/**
 * Delete assocs matching a key from a list of assocs.
 * Requires T to support isList, isAssoc, and cast to list<T>.
 */
template<typename T> inline const list<T> delAssoc(const T& k, const list<T>& p) noexcept {
    if(isNil(p))
        return p;
    const T c = car(p);
    if(isList(c) && k == car<T>(c))
        return delAssoc(k, cdr(p));
    return cons<T>(c, delAssoc(k, cdr(p)));
}

/**
 * Substitute assocs with matching keys in a list of assocs.
 */
template<typename T> inline const list<list<T> > substAssoc(const T& k, const list<T>& n, const list<list<T> >& p, const bool add = false) noexcept {
    if(isNil(p))
        return add? mklist<list<T> >(n) : p;
    if(k == car(car(p)))
        return cons<list<T> >(n, substAssoc(k, n, cdr(p), false));
    return cons<list<T> >(car(p), substAssoc(k, n, cdr(p), add));
}

/**
 * Substitute assocs with matching keys in a list of assocs.
 * Requires T to support isList, isAssoc, and cast to list<T>.
 */
template<typename T> inline const list<T> substAssoc(const T& k, const list<T>& n, const list<T>& p, const bool add = false) noexcept {
    if(isNil(p))
        return add? mklist<T>(n) : p;
    const T c = car(p);
    if(isList(c) && k == car<T>(c))
        return cons<T>(n, substAssoc(k, n, cdr(p), false));
    return cons<T>(c, substAssoc(k, n, cdr(p), add));
}

}

#endif /* tuscany_list_hpp */
