//
//  ========================================================================
//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.server;

import java.util.Enumeration;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

/* ------------------------------------------------------------ */
/** Byte range inclusive of end points.
 * <PRE>
 * 
 *   parses the following types of byte ranges:
 * 
 *       bytes=100-499
 *       bytes=-300
 *       bytes=100-
 *       bytes=1-2,2-3,6-,-2
 *
 *   given an entity length, converts range to string
 * 
 *       bytes 100-499/500
 * 
 * </PRE>
 * 
 * Based on RFC2616 3.12, 14.16, 14.35.1, 14.35.2
 * @version $version$
 * 
 */
public class InclusiveByteRange 
{
    private static final Logger LOG = Log.getLogger(InclusiveByteRange.class);

    long first = 0;
    long last  = 0;    

    public InclusiveByteRange(long first, long last)
    {
        this.first = first;
        this.last = last;
    }
    
    public long getFirst()
    {
        return first;
    }

    public long getLast()
    {
        return last;
    }    


    
    /* ------------------------------------------------------------ */
    /** 
     * @param headers Enumeration of Range header fields.
     * @param size Size of the resource.
     * @return LazyList of satisfiable ranges
     */
    public static List satisfiableRanges(Enumeration headers, long size)
    {
        Object satRanges=null;
        
        // walk through all Range headers
    headers:
        while (headers.hasMoreElements())
        {
            String header = (String) headers.nextElement();
            StringTokenizer tok = new StringTokenizer(header,"=,",false);
            String t=null;
            try
            {
                // read all byte ranges for this header 
                while (tok.hasMoreTokens())
                {
                    try
                    {
                        t = tok.nextToken().trim();

                        long first = -1;
                        long last = -1;
                        int d = t.indexOf('-');
                        if (d < 0 || t.indexOf("-",d + 1) >= 0)
                        {
                            if ("bytes".equals(t))
                                continue;
                            LOG.warn("Bad range format: {}",t);
                            continue headers;
                        }
                        else if (d == 0)
                        {
                            if (d + 1 < t.length())
                                last = Long.parseLong(t.substring(d + 1).trim());
                            else
                            {
                                LOG.warn("Bad range format: {}",t);
                                continue;
                            }
                        }
                        else if (d + 1 < t.length())
                        {
                            first = Long.parseLong(t.substring(0,d).trim());
                            last = Long.parseLong(t.substring(d + 1).trim());
                        }
                        else
                            first = Long.parseLong(t.substring(0,d).trim());

                        if (first == -1 && last == -1)
                            continue headers;

                        if (first != -1 && last != -1 && (first > last))
                            continue headers;

                        if (first < size)
                        {
                            InclusiveByteRange range = new InclusiveByteRange(first,last);
                            satRanges = LazyList.add(satRanges,range);
                        }
                    }
                    catch (NumberFormatException e)
                    {
                        LOG.warn("Bad range format: {}",t);
                        LOG.ignore(e);
                        continue;
                    }
                }
            }
            catch(Exception e)
            {
                LOG.warn("Bad range format: {}",t);
                LOG.ignore(e);
            }    
        }
        return LazyList.getList(satRanges,true);
    }

    /* ------------------------------------------------------------ */
    public long getFirst(long size)
    {
        if (first<0)
        {
            long tf=size-last;
            if (tf<0)
                tf=0;
            return tf;
        }
        return first;
    }
    
    /* ------------------------------------------------------------ */
    public long getLast(long size)
    {
        if (first<0)
            return size-1;
        
        if (last<0 ||last>=size)
            return size-1;
        return last;
    }
    
    /* ------------------------------------------------------------ */
    public long getSize(long size)
    {
        return getLast(size)-getFirst(size)+1;
    }


    /* ------------------------------------------------------------ */
    public String toHeaderRangeString(long size)
    {
        StringBuilder sb = new StringBuilder(40);
        sb.append("bytes ");
        sb.append(getFirst(size));
        sb.append('-');
        sb.append(getLast(size));
        sb.append("/");
        sb.append(size);
        return sb.toString();
    }

    /* ------------------------------------------------------------ */
    public static String to416HeaderRangeString(long size)
    {
        StringBuilder sb = new StringBuilder(40);
        sb.append("bytes */");
        sb.append(size);
        return sb.toString();
    }


    /* ------------------------------------------------------------ */
    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder(60);
        sb.append(Long.toString(first));
        sb.append(":");
        sb.append(Long.toString(last));
        return sb.toString();
    }


}



