/*
 * Copyright (C) 2013 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.tradefed.command.remote;

import com.android.tradefed.log.LogUtil.CLog;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * Encapsulates data for a remote operation sent over the wire.
 */
abstract class RemoteOperation {
    private static final String TYPE = "type";
    private static final String VERSION = "version";
    static final int CURRENT_PROTOCOL_VERSION = 1;

    @SuppressWarnings("serial")
    static class RemoteException extends Exception {
        RemoteException(Throwable t) {
            super(t);
        }

        RemoteException(String msg) {
            super(msg);
        }
    }

    /**
     * Represents all types of remote operations that can be performed
     */
    enum OperationType {
        ALLOCATE_DEVICE, FREE_DEVICE, CLOSE, ADD_COMMAND
    }

    /**
     * Create and populate a {@link RemoteOperation} from given data.
     *
     * @param data the data to parse
     * @throws RemoteException
     */
    final static RemoteOperation createRemoteOpFromString(String data) throws RemoteException {
        try {
            JSONObject jsonData = new JSONObject(data);
            int protocolVersion = jsonData.getInt(VERSION);
            // to keep things simple for now, just barf when protocol version is unknown
            if (protocolVersion != CURRENT_PROTOCOL_VERSION) {
                throw new RemoteException(String.format(
                        "Remote operation has unknown version '%d'. Expected '%d'",
                        protocolVersion, CURRENT_PROTOCOL_VERSION));
            }
            OperationType op = OperationType.valueOf(jsonData.getString(TYPE));
            RemoteOperation rc = null;
            switch (op) {
                case ALLOCATE_DEVICE:
                    rc = new AllocateDeviceOp();
                    break;
                case FREE_DEVICE:
                    rc = new FreeDeviceOp();
                    break;
                case CLOSE:
                    rc = new CloseOp();
                    break;
                case ADD_COMMAND:
                    rc = new AddCommandOp();
                    break;
                default:
                    throw new RemoteException(String.format("unknown remote command '%s'", data));

            }
            rc.unpackFromJson(jsonData);
            return rc;
        } catch (JSONException e) {
            throw new RemoteException(e);
        }
    }

    protected abstract OperationType getType();

    /**
     * Abstract method to allow sub-classes to parse additional data from payload.
     *
     * @param json
     * @throws RemoteException, JSONException
     */
    protected abstract void unpackFromJson(JSONObject json) throws RemoteException, JSONException;

    /**
     * Return the RemoteCommand data in its wire protocol format
     * @return
     */
     String pack() throws RemoteException {
         JSONObject j = new JSONObject();
         try {
             j.put(VERSION, CURRENT_PROTOCOL_VERSION);
             j.put(TYPE, getType().toString());
             packIntoJson(j);
         } catch (JSONException e) {
             CLog.e("Failed to serialize RemoteOperation", e);
         }
         return j.toString();
     }

     /**
      * Callback to add subclass specific data to the JSON object
      * @param j
      * @throws JSONException
      */
    protected abstract void packIntoJson(JSONObject j) throws JSONException;

}
