//  This software code is made available "AS IS" without warranties of any
//  kind.  You may copy, display, modify and redistribute the software
//  code either by itself or as incorporated into your code; provided that
//  you do not remove any proprietary notices.  Your use of this software
//  code is at your own risk and you waive any claim against Amazon
//  Digital Services, Inc. or its affiliates with respect to your use of
//  this software code. (c) 2006 Amazon Digital Services, Inc. or its
//  affiliates.

package net.noderunner.amazon.s3;

import java.util.Date;
import java.util.regex.Pattern;

/**
 * A class representing a single bucket.
 */
public class Bucket {
	
    /**
     * The name of the bucket.
     */
    private String name;

    /**
     * The bucket's creation date.
     */
    private Date creationDate;
    
    Bucket() {
    }

	/**
	 * Constructs a new Bucket.
	 * 
	 * @param name non-null name
	 */
	public Bucket(String name) {
		if (name == null)
			throw new NullPointerException();
		this.name = name;
	}

	/**
	 * Returns name.
	 */
	public String getName() {
		return name;
	}

	/**
	 * Returns true if specified; length is non-zero.
	 */
	public boolean specified() {
		return name.length() != 0;
	}

	/**
	 * Sets name.
	 */
	void setName(String name) {
		this.name = name;
	}

	/**
	 * Returns creationDate.
	 */
	public Date getCreationDate() {
		return creationDate;
	}

	/**
	 * Sets creationDate.
	 */
	void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}
	
	/**
	 * Returns the name.
	 */
	@Override
	public String toString() {
		return name;
	}
	
	static Pattern bucketPath = Pattern.compile("^[0-9A-Za-z\\.\\-_]*$");
	static Pattern ipv4Pattern = Pattern.compile("^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$");
	static Pattern bucketNamePattern = Pattern.compile("^[a-z0-9]([a-z0-9\\-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9\\-]*[a-z0-9])?)*$");

	/**
	 * Returns true if the bucket name is valid for the calling format.
	 */
	public static boolean validateBucketName(String bucketName, CallingFormat callingFormat) {
	    if (callingFormat == CallingFormat.PATH)
	    {
	        final int MIN_BUCKET_LENGTH = 3;
	        final int MAX_BUCKET_LENGTH = 255;
	
	        return null != bucketName &&
	            bucketName.length() >= MIN_BUCKET_LENGTH &&
	            bucketName.length() <= MAX_BUCKET_LENGTH &&
	            bucketPath.matcher(bucketName).matches();
	    } else {
	        final int MIN_BUCKET_LENGTH = 3;
	        final int MAX_BUCKET_LENGTH = 63;
	
	        // If there wasn't a location-constraint, then the current actual 
	        // restriction is just that no 'part' of the name (i.e. sequence
	        // of characters between any 2 '.'s has to be 63) but the recommendation
	        // is to keep the entire bucket name under 63.
	        return null != bucketName &&
	            bucketName.length() >= MIN_BUCKET_LENGTH &&
	            bucketName.length() <= MAX_BUCKET_LENGTH &&
	            !ipv4Pattern.matcher(bucketName).matches() &&
	            bucketNamePattern.matcher(bucketName).matches();
	    }
	}

	/**
	 * Returns true if the bucket name is valid for the calling format.
	 */
	public boolean validateName(CallingFormat callingFormat) {
		return validateBucketName(name, callingFormat);
	}

}
