/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */

package net.ranides.assira.xml.impl;

import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import net.ranides.assira.collection.maps.MultiMap;
import net.ranides.assira.collection.query.CQuery;
import net.ranides.assira.xml.XMLElement;
import net.ranides.assira.xml.XMLElements;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class W3FlatAttributes extends CElements {
    
    public W3FlatAttributes(CQuery<XMLElement> nodes) {
        super(nodes);
    }
    
    @Override
    public CQuery<XMLElement> stream() {
        return super.stream().unfold(n -> n.attrs().stream());
    }

    @Override
    public XMLElements attrs() {
        return EMPTY;
    }

    @Override
    public XMLElements attrs(String name) {
        return EMPTY;
    }
    
    @Override
    public MultiMap<String, String> map() {
        return new AttrMap();
    }

    private final class AttrMap extends AbstractMap<String, String> implements MultiMap<String, String> {

        @Override
        public Set<Entry<String, String>> entrySet() {
            return new AttrSet();
        }

        @Override
        public Collection<String> getAll(Object key) {
            return W3FlatAttributes.this.stream().filter(n -> n.name().equals(key)).map(n->n.content()).distinct().list();
        }

        @Override
        public String put(String key, String value) {
            W3FlatAttributes.super.stream().each(node -> {
                node.attrs().append(node.document().attr(key).content(value));
            });
            return null;
            
        }
        
    }
    
    private final class AttrSet extends AbstractSet<Entry<String,String>> {
        @Override
        public Iterator<Entry<String, String>> iterator() {
            return W3FlatAttributes.this.stream().<Entry<String,String>>map(n -> new AttrEntry(n)).iterator();
        }
        @Override
        public int size() {
            return W3FlatAttributes.this.stream().size();
        }
    }
    
    private static final class AttrEntry implements Entry<String,String> {

        private final XMLElement element;

        public AttrEntry(XMLElement element) {
            this.element = element;
        }

        @Override
        public String getKey() {
            return element.name();
        }

        @Override
        public String getValue() {
            return element.content();
        }

        @Override
        public String setValue(String value) {
            String prev = element.content();
            element.content(value);
            return prev;
        }
        
    }
}
