/*
 * 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 freemarker.template;

import java.io.Serializable;
import java.util.Date;

import freemarker.template.utility.StringUtil;

/**
 * Represents a version number plus the further qualifiers and build info. This is
 * mostly used for representing a FreeMarker version number, but should also be able
 * to parse the version strings of 3rd party libraries.
 * 
 * @see Configuration#getVersion()
 * 
 * @since 2.3.20
 */
public final class Version implements Serializable {
    
    private final int major;
    private final int minor;
    private final int micro;
    private final String extraInfo;
    private final String originalStringValue;
    
    private final Boolean gaeCompliant;
    private final Date buildDate;
    
    private final int intValue;
    private volatile String calculatedStringValue;  // not final because it's calculated on demand
    private int hashCode;  // not final because it's calculated on demand

    /**
     * @throws IllegalArgumentException if the version string is malformed
     */
    public Version(String stringValue) {
        this(stringValue, null, null);
    }
    
    /**
     * @throws IllegalArgumentException if the version string is malformed
     */
    public Version(String stringValue, Boolean gaeCompliant, Date buildDate) {
        stringValue = stringValue.trim();
        originalStringValue = stringValue; 
        
        int[] parts = new int[3];
        String extraInfoTmp = null;
        {
            int partIdx = 0;
            for (int i = 0; i < stringValue.length(); i++) {
                char c = stringValue.charAt(i);
                if (isNumber(c)) {
                    parts[partIdx] = parts[partIdx] * 10 + (c - '0');
                } else {
                    if (i == 0) {
                        throw new IllegalArgumentException(
                                "The version number string " + StringUtil.jQuote(stringValue)
                                + " doesn't start with a number.");
                    }
                    if (c == '.') {
                        char nextC = i + 1 >= stringValue.length() ? 0 : stringValue.charAt(i + 1);
                        if (nextC == '.') {
                            throw new IllegalArgumentException(
                                    "The version number string " + StringUtil.jQuote(stringValue)
                                    + " contains multiple dots after a number.");
                        }
                        if (partIdx == 2 || !isNumber(nextC)) {
                            extraInfoTmp = stringValue.substring(i);
                            break;
                        } else {
                            partIdx++;
                        }
                    } else {
                        extraInfoTmp = stringValue.substring(i);
                        break;
                    }
                }
            }
            
            if (extraInfoTmp != null) {
                char firstChar = extraInfoTmp.charAt(0); 
                if (firstChar == '.' || firstChar == '-' || firstChar == '_') {
                    extraInfoTmp = extraInfoTmp.substring(1);
                    if (extraInfoTmp.length() == 0) {
                        throw new IllegalArgumentException(
                            "The version number string " + StringUtil.jQuote(stringValue)
                            + " has an extra info section opened with \"" + firstChar + "\", but it's empty.");
                    }
                }
            }
        }
        extraInfo = extraInfoTmp;
        
        major = parts[0];
        minor = parts[1];
        micro = parts[2];
        intValue = calculateIntValue();
        
        this.gaeCompliant = gaeCompliant;
        this.buildDate = buildDate;
        
    }

    private boolean isNumber(char c) {
        return c >= '0' && c <= '9';
    }

    public Version(int major, int minor, int micro) {
        this(major, minor, micro, null, null, null);
    }

    /**
     * Creates an object based on the {@code int} value that uses the same kind of encoding as {@link #intValue()}.
     * 
     * @since 2.3.24
     */
    public Version(int intValue) {
        this.intValue = intValue;
        
        this.micro = intValue % 1000;
        this.minor = (intValue / 1000) % 1000;
        this.major = intValue / 1000000;
        
        this.extraInfo = null;
        this.gaeCompliant = null;
        this.buildDate = null;
        originalStringValue = null;
    }
    
    public Version(int major, int minor, int micro, String extraInfo, Boolean gaeCompatible, Date buildDate) {
        this.major = major;
        this.minor = minor;
        this.micro = micro;
        this.extraInfo = extraInfo;
        this.gaeCompliant = gaeCompatible;
        this.buildDate = buildDate;
        intValue = calculateIntValue();
        originalStringValue = null;
    }

    private int calculateIntValue() {
        return intValueFor(major, minor, micro);
    }
    
    static public int intValueFor(int major, int minor, int micro) {
        return major * 1000000 + minor * 1000 + micro;
    }
    
    private String getStringValue() {
        if (originalStringValue != null) return originalStringValue;
        
        String calculatedStringValue = this.calculatedStringValue;
        if (calculatedStringValue == null) {
            synchronized (this) {
                calculatedStringValue = this.calculatedStringValue;
                if (calculatedStringValue == null) {
                    calculatedStringValue = major + "." + minor + "." + micro;
                    if (extraInfo != null) calculatedStringValue += "-" + extraInfo;
                    this.calculatedStringValue = calculatedStringValue;
                }
            }
        }
        return calculatedStringValue;
    }
    
    /**
     * Contains the major.minor.micor numbers and the extraInfo part, not the other information.
     */
    @Override
    public String toString() {
        return getStringValue();
    }

    /**
     * The 1st version number, like 1 in "1.2.3".
     */
    public int getMajor() {
        return major;
    }

    /**
     * The 2nd version number, like 2 in "1.2.3".
     */
    public int getMinor() {
        return minor;
    }

    /**
     * The 3rd version number, like 3 in "1.2.3".
     */
    public int getMicro() {
        return micro;
    }

    /**
     * The arbitrary string after the micro version number without leading dot, dash or underscore,
     * like "RC03" in "2.4.0-RC03".
     * This is usually a qualifier (RC, SNAPHOST, nightly, beta, etc) and sometimes build info (like
     * date).
     */
    public String getExtraInfo() {
        return extraInfo;
    }
    
    /**
     * @return The Google App Engine compliance, or {@code null}.
     */
    public Boolean isGAECompliant() {
        return gaeCompliant;
    }

    /**
     * @deprecated Will always return {@code null} for the FreeMarker version, as we can't store the build date anymore
     * in the jar, in order to have a reproducible build.
     *
     * @return The build date if known, or {@code null}.
     */
    public Date getBuildDate() {
        return buildDate;
    }

    /**
     * @return major * 1000000 + minor * 1000 + micro.
     */
    public int intValue() {
        return intValue;
    }

    @Override
    public int hashCode() {
        int r = hashCode;
        if (r != 0) return r;
        synchronized (this) {
            if (hashCode == 0) {
                final int prime = 31;
                int result = 1;
                result = prime * result + (buildDate == null ? 0 : buildDate.hashCode());
                result = prime * result + (extraInfo == null ? 0 : extraInfo.hashCode());
                result = prime * result + (gaeCompliant == null ? 0 : gaeCompliant.hashCode());
                result = prime * result + intValue;
                if (result == 0) result = -1;  // 0 is reserved for "not set"
                hashCode = result;
            }
            return hashCode;
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;

        Version other = (Version) obj;

        if (intValue != other.intValue) return false;
        
        if (other.hashCode() != hashCode()) return false;
        
        if (buildDate == null) {
            if (other.buildDate != null) return false;
        } else if (!buildDate.equals(other.buildDate)) {
            return false;
        }
        
        if (extraInfo == null) {
            if (other.extraInfo != null) return false;
        } else if (!extraInfo.equals(other.extraInfo)) {
            return false;
        }
        
        if (gaeCompliant == null) {
            if (other.gaeCompliant != null) return false;
        } else if (!gaeCompliant.equals(other.gaeCompliant)) {
            return false;
        }
        
        return true;
    }
    
}
