/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 com.android.server.wifi.hotspot2.soap;

import android.annotation.NonNull;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;

/**
 * This class represents sppUpdateResponse message, as part of the
 * Subscription Provisioning Protocol.
 * For the detail, refer to the Hotspot 2.0 rel2 specification.
 */
public class UpdateResponseMessage {

    /**
     * Serialize the given request to a SOAP envelope.
     *
     * @param sessionId session id generated by the server to identify the session between device
     *                  and server.
     * @param isError {@code true} if the error happens during updating or installing PPS MO.
     * @return {@link SoapSerializationEnvelope}
     */
    public static SoapSerializationEnvelope serializeToSoapEnvelope(@NonNull String sessionId,
            boolean isError) {
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
        envelope.implicitTypes = true;       // Do not include type in element attribute
        envelope.setAddAdornments(false);    // Do not generate/include IDs for each element

        SoapObject requestObject =
                new SoapObject(SoapEnvelope.NS20, SppConstants.METHOD_UPDATE_RESPONSE);
        requestObject.addAttribute(SoapEnvelope.NS20, SppConstants.ATTRIBUTE_SPP_VERSION,
                SppConstants.SUPPORTED_SPP_VERSION);
        requestObject.addAttribute(SoapEnvelope.NS20, SppConstants.ATTRIBUTE_SESSION_ID, sessionId);
        if (isError) {
            requestObject.addAttribute(SoapEnvelope.NS20, SppConstants.ATTRIBUTE_SPP_STATUS,
                    SppConstants.mapStatusIntToString(SppConstants.SppStatus.ERROR));
            SoapObject sppError =
                    new SoapObject(SoapEnvelope.NS20, SppConstants.PROPERTY_SPP_ERROR);
            sppError.addAttribute(SppConstants.ATTRIBUTE_ERROR_CODE,
                    SppConstants.mapErrorIntToString(
                            SppConstants.SppError.MO_ADD_OR_UPDATE_FAILED));
            requestObject.addProperty(SoapEnvelope.NS20, SppConstants.PROPERTY_SPP_ERROR, sppError);
        } else {
            requestObject.addAttribute(SoapEnvelope.NS20, SppConstants.ATTRIBUTE_SPP_STATUS,
                    SppConstants.mapStatusIntToString(SppConstants.SppStatus.OK));
        }

        envelope.setOutputSoapObject(requestObject);
        return envelope;
    }
}
