// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.asn1;

import org.bouncycastle.util.Arrays;
import java.io.IOException;
import java.util.Locale;
import java.util.TimeZone;
import java.util.SimpleTimeZone;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.ParseException;
import org.bouncycastle.util.Strings;

public class ASN1GeneralizedTime extends ASN1Primitive
{
    static final ASN1UniversalType TYPE;
    final byte[] contents;
    
    public static ASN1GeneralizedTime getInstance(final Object o) {
        if (o == null || o instanceof ASN1GeneralizedTime) {
            return (ASN1GeneralizedTime)o;
        }
        if (o instanceof ASN1Encodable) {
            final ASN1Primitive asn1Primitive = ((ASN1Encodable)o).toASN1Primitive();
            if (asn1Primitive instanceof ASN1GeneralizedTime) {
                return (ASN1GeneralizedTime)asn1Primitive;
            }
        }
        if (o instanceof byte[]) {
            try {
                return (ASN1GeneralizedTime)ASN1GeneralizedTime.TYPE.fromByteArray((byte[])o);
            }
            catch (final Exception ex) {
                throw new IllegalArgumentException("encoding error in getInstance: " + ex.toString());
            }
        }
        throw new IllegalArgumentException("illegal object in getInstance: " + o.getClass().getName());
    }
    
    public static ASN1GeneralizedTime getInstance(final ASN1TaggedObject asn1TaggedObject, final boolean b) {
        return (ASN1GeneralizedTime)ASN1GeneralizedTime.TYPE.getContextTagged(asn1TaggedObject, b);
    }
    
    public static ASN1GeneralizedTime getTagged(final ASN1TaggedObject asn1TaggedObject, final boolean b) {
        return (ASN1GeneralizedTime)ASN1GeneralizedTime.TYPE.getTagged(asn1TaggedObject, b);
    }
    
    public ASN1GeneralizedTime(final String s) {
        this.contents = Strings.toByteArray(s);
        try {
            this.getDate();
        }
        catch (final ParseException ex) {
            throw new IllegalArgumentException("invalid date string: " + ex.getMessage());
        }
    }
    
    public ASN1GeneralizedTime(final Date date) {
        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss'Z'", LocaleUtil.EN_Locale);
        simpleDateFormat.setTimeZone(new SimpleTimeZone(0, "Z"));
        this.contents = Strings.toByteArray(simpleDateFormat.format(date));
    }
    
    public ASN1GeneralizedTime(final Date date, final Locale locale) {
        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss'Z'", locale);
        simpleDateFormat.setTimeZone(new SimpleTimeZone(0, "Z"));
        this.contents = Strings.toByteArray(simpleDateFormat.format(date));
    }
    
    ASN1GeneralizedTime(final byte[] contents) {
        if (contents.length < 4) {
            throw new IllegalArgumentException("GeneralizedTime string too short");
        }
        this.contents = contents;
        if (!this.isDigit(0) || !this.isDigit(1) || !this.isDigit(2) || !this.isDigit(3)) {
            throw new IllegalArgumentException("illegal characters in GeneralizedTime string");
        }
    }
    
    public String getTimeString() {
        return Strings.fromByteArray(this.contents);
    }
    
    public String getTime() {
        final String fromByteArray = Strings.fromByteArray(this.contents);
        if (fromByteArray.charAt(fromByteArray.length() - 1) == 'Z') {
            return fromByteArray.substring(0, fromByteArray.length() - 1) + "GMT+00:00";
        }
        final int index = fromByteArray.length() - 6;
        final char char1 = fromByteArray.charAt(index);
        if ((char1 == '-' || char1 == '+') && fromByteArray.indexOf("GMT") == index - 3) {
            return fromByteArray;
        }
        final int beginIndex = fromByteArray.length() - 5;
        final char char2 = fromByteArray.charAt(beginIndex);
        if (char2 == '-' || char2 == '+') {
            return fromByteArray.substring(0, beginIndex) + "GMT" + fromByteArray.substring(beginIndex, beginIndex + 3) + ":" + fromByteArray.substring(beginIndex + 3);
        }
        final int beginIndex2 = fromByteArray.length() - 3;
        final char char3 = fromByteArray.charAt(beginIndex2);
        if (char3 == '-' || char3 == '+') {
            return fromByteArray.substring(0, beginIndex2) + "GMT" + fromByteArray.substring(beginIndex2) + ":00";
        }
        return fromByteArray + this.calculateGMTOffset(fromByteArray);
    }
    
    private String calculateGMTOffset(String pruneFractionalSeconds) {
        String s = "+";
        final TimeZone default1 = TimeZone.getDefault();
        int rawOffset = default1.getRawOffset();
        if (rawOffset < 0) {
            s = "-";
            rawOffset = -rawOffset;
        }
        int n = rawOffset / 3600000;
        final int n2 = (rawOffset - n * 60 * 60 * 1000) / 60000;
        try {
            if (default1.useDaylightTime()) {
                if (this.hasFractionalSeconds()) {
                    pruneFractionalSeconds = this.pruneFractionalSeconds(pruneFractionalSeconds);
                }
                if (default1.inDaylightTime(this.calculateGMTDateFormat().parse(pruneFractionalSeconds + "GMT" + s + this.convert(n) + ":" + this.convert(n2)))) {
                    n += (s.equals("+") ? 1 : -1);
                }
            }
        }
        catch (final ParseException ex) {}
        return "GMT" + s + this.convert(n) + ":" + this.convert(n2);
    }
    
    private SimpleDateFormat calculateGMTDateFormat() {
        SimpleDateFormat simpleDateFormat;
        if (this.hasFractionalSeconds()) {
            simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
        }
        else if (this.hasSeconds()) {
            simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssz");
        }
        else if (this.hasMinutes()) {
            simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmz");
        }
        else {
            simpleDateFormat = new SimpleDateFormat("yyyyMMddHHz");
        }
        simpleDateFormat.setTimeZone(new SimpleTimeZone(0, "Z"));
        return simpleDateFormat;
    }
    
    private String pruneFractionalSeconds(String s) {
        String substring;
        int i;
        char char1;
        for (substring = s.substring(14), i = 1; i < substring.length(); ++i) {
            char1 = substring.charAt(i);
            if ('0' > char1) {
                break;
            }
            if (char1 > '9') {
                break;
            }
        }
        if (i - 1 > 3) {
            s = s.substring(0, 14) + (substring.substring(0, 4) + substring.substring(i));
        }
        else if (i - 1 == 1) {
            s = s.substring(0, 14) + (substring.substring(0, i) + "00" + substring.substring(i));
        }
        else if (i - 1 == 2) {
            s = s.substring(0, 14) + (substring.substring(0, i) + "0" + substring.substring(i));
        }
        return s;
    }
    
    private String convert(final int n) {
        if (n < 10) {
            return "0" + n;
        }
        return Integer.toString(n);
    }
    
    public Date getDate() throws ParseException {
        String source;
        final String s = source = Strings.fromByteArray(this.contents);
        SimpleDateFormat calculateGMTDateFormat;
        if (s.endsWith("Z")) {
            if (this.hasFractionalSeconds()) {
                calculateGMTDateFormat = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'", LocaleUtil.EN_Locale);
            }
            else if (this.hasSeconds()) {
                calculateGMTDateFormat = new SimpleDateFormat("yyyyMMddHHmmss'Z'", LocaleUtil.EN_Locale);
            }
            else if (this.hasMinutes()) {
                calculateGMTDateFormat = new SimpleDateFormat("yyyyMMddHHmm'Z'", LocaleUtil.EN_Locale);
            }
            else {
                calculateGMTDateFormat = new SimpleDateFormat("yyyyMMddHH'Z'", LocaleUtil.EN_Locale);
            }
            calculateGMTDateFormat.setTimeZone(new SimpleTimeZone(0, "Z"));
        }
        else if (s.indexOf(45) > 0 || s.indexOf(43) > 0) {
            source = this.getTime();
            calculateGMTDateFormat = this.calculateGMTDateFormat();
        }
        else {
            if (this.hasFractionalSeconds()) {
                calculateGMTDateFormat = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
            }
            else if (this.hasSeconds()) {
                calculateGMTDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            }
            else if (this.hasMinutes()) {
                calculateGMTDateFormat = new SimpleDateFormat("yyyyMMddHHmm");
            }
            else {
                calculateGMTDateFormat = new SimpleDateFormat("yyyyMMddHH");
            }
            calculateGMTDateFormat.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
        }
        if (this.hasFractionalSeconds()) {
            source = this.pruneFractionalSeconds(source);
        }
        return calculateGMTDateFormat.parse(source);
    }
    
    protected boolean hasFractionalSeconds() {
        for (int i = 0; i != this.contents.length; ++i) {
            if (this.contents[i] == 46 && i == 14) {
                return true;
            }
        }
        return false;
    }
    
    protected boolean hasSeconds() {
        return this.isDigit(12) && this.isDigit(13);
    }
    
    protected boolean hasMinutes() {
        return this.isDigit(10) && this.isDigit(11);
    }
    
    private boolean isDigit(final int n) {
        return this.contents.length > n && this.contents[n] >= 48 && this.contents[n] <= 57;
    }
    
    @Override
    final boolean encodeConstructed() {
        return false;
    }
    
    @Override
    int encodedLength(final boolean b) {
        return ASN1OutputStream.getLengthOfEncodingDL(b, this.contents.length);
    }
    
    @Override
    void encode(final ASN1OutputStream asn1OutputStream, final boolean b) throws IOException {
        asn1OutputStream.writeEncodingDL(b, 24, this.contents);
    }
    
    @Override
    ASN1Primitive toDERObject() {
        return new DERGeneralizedTime(this.contents);
    }
    
    @Override
    boolean asn1Equals(final ASN1Primitive asn1Primitive) {
        return asn1Primitive instanceof ASN1GeneralizedTime && Arrays.areEqual(this.contents, ((ASN1GeneralizedTime)asn1Primitive).contents);
    }
    
    @Override
    public int hashCode() {
        return Arrays.hashCode(this.contents);
    }
    
    static ASN1GeneralizedTime createPrimitive(final byte[] array) {
        return new ASN1GeneralizedTime(array);
    }
    
    static {
        TYPE = new ASN1UniversalType(24) {
            @Override
            ASN1Primitive fromImplicitPrimitive(final DEROctetString derOctetString) {
                return ASN1GeneralizedTime.createPrimitive(derOctetString.getOctets());
            }
        };
    }
}
