/*
 * 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.lenya.cms.jcr.metadata;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Value;

import org.apache.avalon.framework.container.ContainerUtil;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.cocoon.jcr.source.JCRNodeSource;
import org.apache.excalibur.source.SourceResolver;
import org.apache.lenya.cms.metadata.ElementSet;
import org.apache.lenya.cms.metadata.MetaData;
import org.apache.lenya.cms.metadata.MetaDataException;
import org.apache.lenya.cms.publication.DocumentException;
import org.apache.lenya.cms.repository.RepositoryException;

/**
 * JCR based meta data.
 */
public class JCRMetaData extends AbstractLogEnabled implements MetaData {

    private String namespace;
    private String sourceUri;
    protected ServiceManager manager;

    private Map key2values = null;

    /**
     * Ctor.
     * @param namespace
     * @param sourceUri
     * @param manager
     * @param logger
     */
    public JCRMetaData(String namespace, String sourceUri, ServiceManager manager, Logger logger) {
        this.namespace = namespace;
        this.sourceUri = sourceUri;
        this.manager = manager;
        ContainerUtil.enableLogging(this, logger);
    }

    protected Map getKey2Values() {
        if (this.key2values == null) {
            load();
        }
        return this.key2values;
    }

    protected void load() {

        this.key2values = new HashMap();
        SourceResolver resolver = null;
        JCRNodeSource source = null;
        try {
            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
            source = (JCRNodeSource) resolver.resolveURI(this.sourceUri);

            Node node = source.getNode();
            String prefix = node.getSession()
                    .getWorkspace()
                    .getNamespaceRegistry()
                    .getPrefix(this.namespace);
            if (!prefix.equals("")) {
                prefix = prefix + ":";
            }

            String possibleKeys[] = getPossibleKeys();
            for (int i = 0; i < possibleKeys.length; i++) {
                String key = prefix + possibleKeys[i];
                if (node.hasProperty(key)) {
                    Property property = node.getProperty(key);
                    Value[] values = property.getValues();
                    String[] stringValues = new String[values.length];
                    for (int v = 0; v < values.length; v++) {
                        stringValues[v] = values[v].getString();
                    }
                    this.key2values.put(possibleKeys[i], stringValues);
                }
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                this.manager.release(resolver);
            }
        }
    }

    public void save() throws MetaDataException {
        SourceResolver resolver = null;
        JCRNodeSource source = null;
        try {
            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
            source = (JCRNodeSource) resolver.resolveURI(this.sourceUri);

            if (!source.exists()) {
                OutputStream stream = source.getOutputStream();
                stream.flush();
                stream.close();
            }

            Node node = source.getNode();
            String prefix = node.getSession()
                    .getWorkspace()
                    .getNamespaceRegistry()
                    .getPrefix(this.namespace);
            if (!prefix.equals("")) {
                prefix = prefix + ":";
            }

            String possibleKeys[] = getPossibleKeys();
            for (int i = 0; i < possibleKeys.length; i++) {
                String[] stringValues = (String[]) getKey2Values().get(possibleKeys[i]);
                String key = prefix + possibleKeys[i];
                node.setProperty(key, stringValues);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                this.manager.release(resolver);
            }
        }
    }

    public String[] getValues(String key) throws MetaDataException {
        return (String[]) getKey2Values().get(key);
    }

    public String getFirstValue(String key) throws MetaDataException {
        String value = null;
        String[] values = (String[]) getKey2Values().get(key);
        if (values.length > 0) {
            value = values[0];
        }
        return value;
    }

    public void setValue(String key, String value) throws MetaDataException {
        String[] values = { value };
        getKey2Values().put(key, values);
    }

    public void addValue(String key, String value) throws MetaDataException {
        String[] values = (String[]) getKey2Values().get(key);
        List valueList = new ArrayList(Arrays.asList(values));
        valueList.add(value);
        values = (String[]) valueList.toArray(new String[valueList.size()]);
        getKey2Values().put(key, values);
    }

    public void replaceBy(MetaData other) throws MetaDataException {
        this.key2values = new HashMap();
        String[] keys = getPossibleKeys();
        for (int i = 0; i < keys.length; i++) {
            String[] values = other.getValues(keys[i]);
            this.key2values.put(keys[i], values);
        }
        save();
    }

    public void forcedReplaceBy(MetaData other) throws MetaDataException {
        replaceBy(other);
    }
    
    private String[] possibleKeys = new String[0];

    /**
     * @param keys The possible keys.
     */
    public void setPossibleKeys(String[] keys) {
        this.possibleKeys = keys;
    }

    public String[] getPossibleKeys() {
        return this.possibleKeys;
    }

    public boolean isValidAttribute(String key) {
        String[] keys = getPossibleKeys();
        return Arrays.asList(keys).contains(key);
    }

    public HashMap getAvailableKey2Value() {
        // TODO We need to implement this Method!
        return null;
    }

    public long getLastModified() throws MetaDataException {
        long lastModified = 0;
        try {
            SourceResolver resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
            JCRNodeSource source = (JCRNodeSource) resolver.resolveURI(this.sourceUri);
            lastModified = source.getLastModified();
        } catch (Exception e) {
            throw new MetaDataException("Error resolving meta data source", e);
        }
        return lastModified;
    }

    public String[] getAvailableKeys() {
        throw new RuntimeException("not implemented");
    }

    public ElementSet getElementSet() {
        throw new RuntimeException("not implemented");
    }

    public void removeAllValues(String key) throws MetaDataException {
        throw new RuntimeException("not implemented");
    }
}
