/*
 * 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.
 */
/* Apache Harmony HEADER because the code in this class comes mostly from ZipFile, ZipEntry and
 * ZipConstants from android libcore.
 */

package androidx.multidex;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;

class ZipEntryReader {
    static final Charset UTF_8 = Charset.forName("UTF-8");
   /**
     * General Purpose Bit Flags, Bit 0.
     * If set, indicates that the file is encrypted.
     */
    private static final int GPBF_ENCRYPTED_FLAG = 1 << 0;

    /**
     * Supported General Purpose Bit Flags Mask.
     * Bit mask of bits not supported.
     * Note: The only bit that we will enforce at this time
     * is the encrypted bit. Although other bits are not supported,
     * we must not enforce them as this could break some legitimate
     * use cases (See http://b/8617715).
     */
    private static final int GPBF_UNSUPPORTED_MASK = GPBF_ENCRYPTED_FLAG;
    private static final long CENSIG = 0x2014b50;

    static ZipEntry readEntry(ByteBuffer in) throws IOException {

        int sig = in.getInt();
        if (sig != CENSIG) {
             throw new ZipException("Central Directory Entry not found");
        }

        in.position(8);
        int gpbf = in.getShort() & 0xffff;

        if ((gpbf & GPBF_UNSUPPORTED_MASK) != 0) {
            throw new ZipException("Invalid General Purpose Bit Flag: " + gpbf);
        }

        int compressionMethod = in.getShort() & 0xffff;
        int time = in.getShort() & 0xffff;
        int modDate = in.getShort() & 0xffff;

        // These are 32-bit values in the file, but 64-bit fields in this object.
        long crc = ((long) in.getInt()) & 0xffffffffL;
        long compressedSize = ((long) in.getInt()) & 0xffffffffL;
        long size = ((long) in.getInt()) & 0xffffffffL;

        int nameLength = in.getShort() & 0xffff;
        int extraLength = in.getShort() & 0xffff;
        int commentByteCount = in.getShort() & 0xffff;

        // This is a 32-bit value in the file, but a 64-bit field in this object.
        in.position(42);
        long localHeaderRelOffset = ((long) in.getInt()) & 0xffffffffL;

        byte[] nameBytes = new byte[nameLength];
        in.get(nameBytes, 0, nameBytes.length);
        String name = new String(nameBytes, 0, nameBytes.length, UTF_8);

        ZipEntry entry = new ZipEntry(name);
        entry.setMethod(compressionMethod);
        entry.setTime(getTime(time, modDate));

        entry.setCrc(crc);
        entry.setCompressedSize(compressedSize);
        entry.setSize(size);

        // The RI has always assumed UTF-8. (If GPBF_UTF8_FLAG isn't set, the encoding is
        // actually IBM-437.)
        if (commentByteCount > 0) {
            byte[] commentBytes = new byte[commentByteCount];
            in.get(commentBytes, 0, commentByteCount);
            entry.setComment(new String(commentBytes, 0, commentBytes.length, UTF_8));
        }

        if (extraLength > 0) {
            byte[] extra = new byte[extraLength];
            in.get(extra, 0, extraLength);
            entry.setExtra(extra);
        }

        return entry;

    }

    private static long getTime(int time, int modDate) {
        GregorianCalendar cal = new GregorianCalendar();
        cal.set(Calendar.MILLISECOND, 0);
        cal.set(1980 + ((modDate >> 9) & 0x7f), ((modDate >> 5) & 0xf) - 1,
                modDate & 0x1f, (time >> 11) & 0x1f, (time >> 5) & 0x3f,
                (time & 0x1f) << 1);
        return cal.getTime().getTime();
    }

}
