/* ======================================================================
   Parts Copyright 2006 University of Leeds, Oxford University, University of the Highlands and Islands.

   Licensed 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.bodington.server;

import java.util.Enumeration;

import org.apache.log4j.Logger;
import org.bodington.server.resources.Resource;
import org.bodington.server.resources.UploadedFileSummary;
import org.bodington.text.Metadatum;

public class QuotaFactory
{
    
    private static final Logger log = Logger.getLogger(Metadatum.class);
    
    public final static int RESOURCES = 0;
    public final static int FILES = 1;
    
    private final static int QUOTA = 0;
    private final static int USAGE = 1;
    
    final static String properties[][] = new String[][]{
        {"resource-quota", "resource-usage"},
        {"files-quota", "files-usage"}
    };

    public static QuotaMetadatum getQuota(final Resource resource, final int type)
        throws BuildingServerException
    {
        final Metadatum quota = resource.getMetadatum(properties[type][QUOTA]);
        final Metadatum usage = resource.getMetadatum(properties[type][USAGE]);
        

        
        // If we don't have any quotas return a new Quota.
        if (quota == null || usage == null || quota.getValue() == null
            || usage.getValue() == null)
            return new QuotaMetadatum() {
            
                private Metadatum quota, usage;
                private long quotaValue = 0, usageValue = 0;
                
                public long getQuota()
                {
                    return quotaValue;
                }

                public Resource getResource()
                {
                    return resource;
                }

                public long getUsage()
                {
                    return usageValue;
                }

                public void adjustUsage(long x) throws BuildingServerException
                {
                    if (!hasQuota())
                        return;
                    usageValue += x;
                    usage.save();
                }

                public Object getLock()
                {
                    return (usage == null)?new Object():usage;
                }

                public void setQuota(long x) throws BuildingServerException
                {
                    if (resource.findChildren().hasMoreElements())
                        throw new BuildingServerException("Can't set quota on resource with children");
                    quotaValue = x;
                    quota = new Metadatum(resource.getPrimaryKey(), 
                        properties[type][QUOTA], String.valueOf(quotaValue));
                    quota.save();
                    // Save the usage as 0
                    usage = new Metadatum(resource.getPrimaryKey(),
                        properties[type][USAGE], String.valueOf(usageValue));
                    usage.save();
                }
                
                public boolean hasQuota()
                {
                    return quota != null;
                }
                
            };
        final long quotaValue, usageValue;
        try
        {
            quotaValue = Integer.parseInt(quota.getValue());
            usageValue = Integer.parseInt(usage.getValue());
        }
        catch (NumberFormatException nfe)
        {
            log.error("Problem finding quota. Quota: " + quota.getValue()
                + " Usage: " + usage.getValue() + " Resource: "
                + resource.getPrimaryKey());
            throw new BuildingServerException("Failed to load quotas");
        }
        
        if (!quota.getObjectId().equals(usage.getObjectId()))
            log.error("Quota and Usage do not match to the same resource.");
        
        final Resource quotaResource = Resource.findResource(quota.getObjectId());
        
        return new QuotaMetadatum() {
            
            private long quotaPrivate = quotaValue;
            private long usagePrivate = usageValue;
            
            public long getQuota()
            {
                return quotaPrivate;
            }

            public Resource getResource()
            {
                return quotaResource;
            }

            public long getUsage()
            {
                return usagePrivate;
            }

            public void adjustUsage(long x) throws BuildingServerException
            {
                usagePrivate += x;
                usage.setValue(String.valueOf(usagePrivate));
                usage.save();
            }

            public Object getLock()
            {
                return usage;
            }

            public void setQuota(long x) throws BuildingServerException
            {
                quotaPrivate = x;
                quota.setValue(String.valueOf(quotaPrivate));
                quota.save();
            }
            
            public boolean hasQuota()
            {
                return true;
            }
            
            };
        
    }
    /**
    
    public static long calculate(Resource resource, int type)
    {
        long total = 0;
        if (type == FILES)
        {
            total += calculateFiles(resource);
        }
        resource.findChildren();
    }
    **/

}
