/**
 *  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 org.apache.kerby.kerberos.kerb.ccache;

import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
import org.apache.kerby.kerberos.kerb.type.ticket.Ticket;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

public class CredentialCache implements KrbCredentialCache {
    public static final int FCC_FVNO_1 = 0x501;
    public static final int FCC_FVNO_2 = 0x502;
    public static final int FCC_FVNO_3 = 0x503;
    public static final int FCC_FVNO_4 = 0x504;

    public static final int FCC_TAG_DELTATIME = 1;
    private final List<Credential> credentials;
    private int version = FCC_FVNO_4;
    private List<Tag> tags;
    private PrincipalName primaryPrincipal;

    public CredentialCache() {
        credentials = new ArrayList<>();
    }

    public CredentialCache(TgtTicket tgt) {
        this();
        addCredential(new Credential(tgt));
        setPrimaryPrincipal(tgt.getClientPrincipal());
    }

    public CredentialCache(SgtTicket sgt) {
        this();
        addCredential(new Credential(sgt, sgt.getClientPrincipal()));
        setPrimaryPrincipal(sgt.getClientPrincipal());
    }

    public CredentialCache(Credential credential) {
        this();
        addCredential(credential);
        setPrimaryPrincipal(credential.getClientName());
    }

    public static void main(String[] args) throws IOException {
        if (args.length != 2) {
            System.err.println("Dump credential cache file");
            System.err.println("Usage: CredentialCache <ccache-file>");
            System.exit(1);
        }

        String cacheFile = args[1];
        CredentialCache cc = new CredentialCache();
        cc.load(new File(cacheFile));

        for (Credential cred : cc.getCredentials()) {
            Ticket tkt = cred.getTicket();
            System.out.println("Tkt server name: " + tkt.getSname().getName());
            System.out.println("Tkt client name: " + cred.getClientName().getName());
            System.out.println("Tkt encrypt type: " + tkt.getEncryptedEncPart().getEType().getName());
        }
    }

    @Override
    public void store(File ccacheFile) throws IOException {
        try (OutputStream outputStream = Files.newOutputStream(ccacheFile.toPath())) {
            store(outputStream);
        }
    }

    @Override
    public void store(OutputStream outputStream) throws IOException {
        if (outputStream == null) {
            throw new IllegalArgumentException("Invalid and null output stream");
        }

        CredCacheOutputStream ccos = new CredCacheOutputStream(outputStream);

        doStore(ccos);

        ccos.close();
    }

    private void doStore(CredCacheOutputStream ccos) throws IOException {
        this.version = FCC_FVNO_3;

        writeVersion(ccos);

        if (version == FCC_FVNO_4) {
            writeTags(ccos);
        }

        ccos.writePrincipal(primaryPrincipal, version);

        for (Credential cred : credentials) {
            cred.store(ccos, version);
        }
    }

    @Override
    public PrincipalName getPrimaryPrincipal() {
        return primaryPrincipal;
    }

    @Override
    public void setPrimaryPrincipal(PrincipalName principal) {
        primaryPrincipal = principal;
    }

    @Override
    public int getVersion() {
        return version;
    }

    @Override
    public void setVersion(int version) {
        this.version = version;
    }

    public List<Tag> getTags() {
        return this.tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }

    @Override
    public List<Credential> getCredentials() {
        return credentials;
    }

    @Override
    public void addCredential(Credential credential) {
        if (credential != null) {
            for (Credential cred : this.credentials) {
                if (cred.getServerName().getName().equals(credential.getServerName().getName())) {
                    return;
                }
            }
            this.credentials.add(credential);
        }
    }

    @Override
    public void addCredentials(List<Credential> credentials) {
        if (credentials != null) {
            this.credentials.addAll(credentials);
        }
    }

    @Override
    public void removeCredentials(List<Credential> credentials) {
        if (credentials != null) {
            for (Credential cred : credentials) {
                removeCredential(cred);
            }
        }
    }

    @Override
    public void removeCredential(Credential credential) {
        if (credential != null) {
            for (Credential cred : credentials) {
                if (cred.equals(credential)) {
                    credentials.remove(cred);
                    break;
                }
            }
        }
    }

    @Override
    public void load(File ccacheFile) throws IOException {
        if (!ccacheFile.exists() || !ccacheFile.canRead()) {
            throw new IllegalArgumentException("Invalid ccache file: "
                    + ccacheFile.getAbsolutePath());
        }

        try (InputStream inputStream = Files.newInputStream(ccacheFile.toPath())) {
            load(inputStream);
        }
    }

    @Override
    public void load(InputStream inputStream) throws IOException {
        if (inputStream == null) {
            throw new IllegalArgumentException("Invalid and null input stream");
        }

        CredCacheInputStream ccis = new CredCacheInputStream(inputStream);

        doLoad(ccis);

        ccis.close();
    }

    private void doLoad(CredCacheInputStream ccis) throws IOException {
        this.version = readVersion(ccis);
        if (version == FCC_FVNO_4) {
            this.tags = readTags(ccis);
        }

        this.primaryPrincipal = ccis.readPrincipal(version);

        this.credentials.addAll(readCredentials(ccis));
    }

    private List<Credential> readCredentials(CredCacheInputStream ccis)
            throws IOException {
        List<Credential> results = new ArrayList<>(2);

        Credential cred;
        while (ccis.available() > 0) {
            cred = new Credential();
            cred.load(ccis, version);

            results.add(cred);
        }

        return results;
    }

    private int readVersion(CredCacheInputStream ccis) throws IOException {
        int result = ccis.readShort();
        return result;
    }

    private List<Tag> readTags(CredCacheInputStream ccis) throws IOException {
        int len = ccis.readShort();
        List<Tag> tags = new ArrayList<>();

        int tag, tagLen, time, usec;
        while (len > 0) {
            tag = ccis.readShort();
            tagLen = ccis.readShort();
            switch (tag) {
                case FCC_TAG_DELTATIME:
                    time = ccis.readInt();
                    usec = ccis.readInt();
                    tags.add(new Tag(tag, time, usec));
                    break;
                default:
                    if (ccis.read(new byte[tagLen], 0, tagLen) == -1) { // ignore unknown tag
                        throw new IOException();
                    }
            }
            len = len - (4 + tagLen);
        }

        return tags;
    }

    private void writeVersion(CredCacheOutputStream ccos) throws IOException {
        ccos.writeShort(version);
    }

    private void writeTags(CredCacheOutputStream ccos) throws IOException {
        if (tags == null) {
            ccos.writeShort(0);
            return;
        }

        int length = 0;
        for (Tag tag : tags) {
            if (tag.tag != FCC_TAG_DELTATIME) {
                continue;
            }
            length += tag.length;
        }
        ccos.writeShort(length);

        for (Tag tag : tags) {
            if (tag.tag != CredentialCache.FCC_TAG_DELTATIME) {
                continue;
            }
            writeTag(ccos, tag);
        }
    }

    private void writeTag(CredCacheOutputStream ccos, Tag tag) throws IOException {
        ccos.writeShort(tag.tag);
        ccos.writeShort(tag.length);
        ccos.writeInt(tag.time);
        ccos.writeInt(tag.usec);
    }
}
