/**
 *  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.server.request;

import org.apache.kerby.kerberos.kerb.KrbCodec;
import org.apache.kerby.kerberos.kerb.KrbConstant;
import org.apache.kerby.kerberos.kerb.KrbErrorCode;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
import org.apache.kerby.kerberos.kerb.server.KdcContext;
import org.apache.kerby.kerberos.kerb.type.KerberosTime;
import org.apache.kerby.kerberos.kerb.type.ap.ApOption;
import org.apache.kerby.kerberos.kerb.type.ap.ApReq;
import org.apache.kerby.kerberos.kerb.type.ap.Authenticator;
import org.apache.kerby.kerberos.kerb.type.base.EncryptedData;
import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
import org.apache.kerby.kerberos.kerb.type.base.EncryptionType;
import org.apache.kerby.kerberos.kerb.type.base.HostAddresses;
import org.apache.kerby.kerberos.kerb.type.base.KeyUsage;
import org.apache.kerby.kerberos.kerb.type.base.KrbMessageType;
import org.apache.kerby.kerberos.kerb.type.base.LastReq;
import org.apache.kerby.kerberos.kerb.type.base.LastReqEntry;
import org.apache.kerby.kerberos.kerb.type.base.LastReqType;
import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
import org.apache.kerby.kerberos.kerb.type.kdc.EncKdcRepPart;
import org.apache.kerby.kerberos.kerb.type.kdc.EncTgsRepPart;
import org.apache.kerby.kerberos.kerb.type.kdc.KdcReq;
import org.apache.kerby.kerberos.kerb.type.kdc.TgsRep;
import org.apache.kerby.kerberos.kerb.type.kdc.TgsReq;
import org.apache.kerby.kerberos.kerb.type.pa.PaDataEntry;
import org.apache.kerby.kerberos.kerb.type.ticket.EncTicketPart;
import org.apache.kerby.kerberos.kerb.type.ticket.Ticket;
import org.apache.kerby.kerberos.kerb.type.ticket.TicketFlag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.ByteBuffer;

public class TgsRequest extends KdcRequest {
    private static final Logger LOG = LoggerFactory.getLogger(TgsRequest.class);

    private EncryptionKey tgtSessionKey;
    private Ticket tgtTicket;

    /**
     * @param tgsReq TGS request
     * @param kdcContext kdc context
     */
    public TgsRequest(TgsReq tgsReq, KdcContext kdcContext) {
        super(tgsReq, kdcContext);

        setPreauthRequired(true);
    }

    /**
     * Get tgt session key.
     *
     * @return The tgt session key
     */
    public EncryptionKey getTgtSessionKey() {
        return tgtSessionKey;
    }

    /**
     * Set tgt session key.
     *
     * @param tgtSessionKey The tgt session key
     */
    public void setTgtSessionKey(EncryptionKey tgtSessionKey) {
        this.tgtSessionKey = tgtSessionKey;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void checkClient() throws KrbException {
        // Nothing to do at this phase because client couldn't be checked out yet.
    }

    /**
     * Get tgt ticket.
     *
     * @return The tgt ticket.
     */
    public Ticket getTgtTicket() {
        return tgtTicket;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void issueTicket() throws KrbException {
        TicketIssuer issuer = new ServiceTicketIssuer(this);
        Ticket newTicket = issuer.issueTicket();
        LOG.info("TGS_REQ ISSUE: authtime " + newTicket.getEncPart().getAuthTime().getTime() + ","
                + newTicket.getEncPart().getCname() + " for "
                + newTicket.getSname());
        setTicket(newTicket);
    }

    /**
     * Verify authenticator.
     * @throws org.apache.kerby.kerberos.kerb.KrbException e
     * @param paDataEntry preauthentication data entry
     */
    public void verifyAuthenticator(PaDataEntry paDataEntry) throws KrbException {
        ApReq apReq = KrbCodec.decode(paDataEntry.getPaDataValue(), ApReq.class);

        if (apReq.getPvno() != KrbConstant.KRB_V5) {
            throw new KrbException(KrbErrorCode.KRB_AP_ERR_BADVERSION);
        }

        if (apReq.getMsgType() != KrbMessageType.AP_REQ) {
            throw new KrbException(KrbErrorCode.KRB_AP_ERR_MSG_TYPE);
        }

        tgtTicket = apReq.getTicket();
        EncryptionKey tgsKey;
        EncryptionType encType = tgtTicket.getEncryptedEncPart().getEType();
        String remoteRealm = tgtTicket.getRealm();
        if (checkCrossRealm(remoteRealm)) {
            KrbIdentity tgs = getCrossRealmTgsEntry(remoteRealm);
            if (tgs != null) {
                tgsKey = tgs.getKey(encType);
            } else {
                throw new KrbException("Fail to get the tgs entry for remote realm: " + remoteRealm);
            }
        } else {
            tgsKey = getTgsEntry().getKeys().get(encType);
        }
        if (tgsKey == null) {
            throw new KrbException("Fail to get the tgs key for the type: " + encType);
        }

        if (tgtTicket.getTktvno() != KrbConstant.KRB_V5) {
            throw new KrbException(KrbErrorCode.KRB_AP_ERR_BADVERSION);
        }

        EncTicketPart encPart = EncryptionUtil.unseal(tgtTicket.getEncryptedEncPart(),
            tgsKey, KeyUsage.KDC_REP_TICKET, EncTicketPart.class);
        tgtTicket.setEncPart(encPart);

        EncryptionKey encKey = null;
        //if (apReq.getApOptions().isFlagSet(ApOptions.USE_SESSION_KEY)) {
        encKey = tgtTicket.getEncPart().getKey();

        if (encKey == null) {
            throw new KrbException(KrbErrorCode.KRB_AP_ERR_NOKEY);
        }

        Authenticator authenticator = EncryptionUtil.unseal(apReq.getEncryptedAuthenticator(),
            encKey, KeyUsage.TGS_REQ_AUTH, Authenticator.class);

        if (!authenticator.getCname().equals(tgtTicket.getEncPart().getCname())) {
            throw new KrbException(KrbErrorCode.KRB_AP_ERR_BADMATCH);
        }

        HostAddresses hostAddresses = tgtTicket.getEncPart().getClientAddresses();
        if (hostAddresses == null || hostAddresses.isEmpty()) {
            if (!getKdcContext().getConfig().isEmptyAddressesAllowed()) {
                throw new KrbException(KrbErrorCode.KRB_AP_ERR_BADADDR);
            }
        } else if (!hostAddresses.contains(getClientAddress())) {
            throw new KrbException(KrbErrorCode.KRB_AP_ERR_BADADDR);
        }

        PrincipalName serverPrincipal = tgtTicket.getSname();
        serverPrincipal.setRealm(tgtTicket.getRealm());

        /* The client principal does not exist in backend when it's a cross realm request */
        if (authenticator.getCrealm() != null
            && authenticator.getCrealm().equals(getKdcContext().getKdcRealm())) {
            PrincipalName clientPrincipal = authenticator.getCname();
            clientPrincipal.setRealm(authenticator.getCrealm());
            KrbIdentity clientEntry = getEntry(clientPrincipal.getName());
            setClientEntry(clientEntry);
        }

        if (!authenticator.getCtime().isInClockSkew(
            getKdcContext().getConfig().getAllowableClockSkew() * 1000)) {
            throw new KrbException(KrbErrorCode.KRB_AP_ERR_SKEW);
        }

        KerberosTime now = KerberosTime.now();
        KerberosTime startTime = tgtTicket.getEncPart().getStartTime();
        if (startTime == null) {
            startTime = tgtTicket.getEncPart().getAuthTime();
        }
        if (!startTime.lessThan(now)) {
            throw new KrbException(KrbErrorCode.KRB_AP_ERR_TKT_NYV);
        }

        KerberosTime endTime = tgtTicket.getEncPart().getEndTime();
        if (!endTime.greaterThan(now)) {
            throw new KrbException(KrbErrorCode.KRB_AP_ERR_TKT_EXPIRED);
        }

        apReq.getApOptions().setFlag(ApOption.MUTUAL_REQUIRED);

        setTgtSessionKey(tgtTicket.getEncPart().getKey());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void makeReply() throws KrbException {
        Ticket ticket = getTicket();

        TgsRep reply = new TgsRep();

        if (getClientEntry() == null) {
            reply.setCname(ticket.getEncPart().getCname());
            reply.setCrealm(ticket.getEncPart().getCrealm());
        } else {
            reply.setCname(getClientEntry().getPrincipal());
            reply.setCrealm(getKdcContext().getKdcRealm());
        }

        reply.setTicket(ticket);

        EncKdcRepPart encKdcRepPart = makeEncKdcRepPart();
        reply.setEncPart(encKdcRepPart);

        EncryptionKey sessionKey;
        if (getToken() != null) {
            sessionKey = getSessionKey();
        } else {
            sessionKey = getTgtSessionKey();
        }
        EncryptedData encryptedData = EncryptionUtil.seal(encKdcRepPart,
            sessionKey, KeyUsage.TGS_REP_ENCPART_SESSKEY);
        reply.setEncryptedEncPart(encryptedData);

        setReply(reply);
    }

    /**
     * Make EncKdcRepPart.
     * @return encryption kdc response part
     */
    private EncKdcRepPart makeEncKdcRepPart() {
        KdcReq request = getKdcReq();
        Ticket ticket = getTicket();

        EncKdcRepPart encKdcRepPart = new EncTgsRepPart();

        //session key
        encKdcRepPart.setKey(ticket.getEncPart().getKey());

        LastReq lastReq = new LastReq();
        LastReqEntry entry = new LastReqEntry();
        entry.setLrType(LastReqType.THE_LAST_INITIAL);
        entry.setLrValue(new KerberosTime());
        lastReq.add(entry);
        encKdcRepPart.setLastReq(lastReq);

        encKdcRepPart.setNonce(request.getReqBody().getNonce());

        encKdcRepPart.setFlags(ticket.getEncPart().getFlags());
        encKdcRepPart.setAuthTime(ticket.getEncPart().getAuthTime());
        encKdcRepPart.setStartTime(ticket.getEncPart().getStartTime());
        encKdcRepPart.setEndTime(ticket.getEncPart().getEndTime());

        if (ticket.getEncPart().getFlags().isFlagSet(TicketFlag.RENEWABLE)) {
            encKdcRepPart.setRenewTill(ticket.getEncPart().getRenewtill());
        }

        encKdcRepPart.setSname(ticket.getSname());
        encKdcRepPart.setSrealm(ticket.getRealm());
        encKdcRepPart.setCaddr(ticket.getEncPart().getClientAddresses());

        return encKdcRepPart;
    }

    /**
     * @return request body
     * @throws KrbException e
     */
    public ByteBuffer getRequestBody() throws KrbException {
        return null;
    }
}
