/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed 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.openehealth.ipf.platform.camel.ihe.hl7v3.iti55;

import java.util.Map;

import jakarta.xml.bind.JAXBException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.namespace.QName;

import org.apache.camel.Message;
import org.apache.cxf.headers.Header;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.openehealth.ipf.platform.camel.ihe.ws.HeaderUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

/**
 * Helper functions for handling TTL SOAP header in XCPD.
 * @author Dmytro Rud
 */
public class TtlHeaderUtils {

    private static final QName TTL_HEADER_QNAME = new QName("urn:ihe:iti:xcpd:2009", "CorrelationTimeToLive"); 
    
    private TtlHeaderUtils() {
        throw new IllegalStateException("cannot instantiate utility class");
    }
    
    
    /**
     * Returns the XCPD TTL value stored in incoming SOAP headers associated   
     * with the given message, or <code>null</code>, when none found.
     */
    public static Duration getTtl(Message message) {
        Map<QName, Header> soapHeaders = HeaderUtils.getIncomingSoapHeaders(message);
        if ((soapHeaders != null) && soapHeaders.containsKey(TTL_HEADER_QNAME)) {
            var o = soapHeaders.get(TTL_HEADER_QNAME).getObject();
            if (o instanceof Element element) {
                var child = element.getFirstChild();
                if (child instanceof Text) {
                    var value = child.getNodeValue();
                    try {
                        return DatatypeFactory.newInstance().newDuration(value);
                    } catch (Exception e) {
                        throw new RuntimeException("Cannot parse TTL header " + value, e); 
                    }
                }
            }
        }
        return null;
    }
    
    
    /**
     * Stores the user-defined XCPD TTL value into outgoing SOAP headers    
     * associated with the given message.
     */
    public static void setTtl(Duration dura, Message message) {
        HeaderUtils.addOutgoingSoapHeaders(message, new Header(TTL_HEADER_QNAME, dura.toString(), getStringDataBinding()));
    }
    
    
    private static JAXBDataBinding getStringDataBinding() {
        try {
            return new JAXBDataBinding(String.class);
        } catch (JAXBException e) {
            // actually cannot occur
            throw new RuntimeException(e);
        }
    }
}
