/*
 * 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.
 */
 
#ifndef __SESSIONCREDENTIALS_H__
#define __SESSIONCREDENTIALS_H__

#include "RocketMQClient.h"

namespace rocketmq {

class SessionCredentials {
 public:
  static const std::string AccessKey;
  static const std::string SecretKey;
  static const std::string Signature;
  static const std::string SignatureMethod;
  static const std::string ONSChannelKey;

  SessionCredentials(std::string input_accessKey, std::string input_secretKey,
                     const std::string& input_authChannel)
      : accessKey(input_accessKey),
        secretKey(input_secretKey),
        authChannel(input_authChannel) {}
  SessionCredentials() : authChannel("ALIYUN") {}
  ~SessionCredentials() {}

  std::string getAccessKey() const { return accessKey; }

  void setAccessKey(std::string input_accessKey) { accessKey = input_accessKey; }

  std::string getSecretKey() const { return secretKey; }

  void setSecretKey(std::string input_secretKey) { secretKey = input_secretKey; }

  std::string getSignature() const { return signature; }

  void setSignature(std::string input_signature) { signature = input_signature; }

  std::string getSignatureMethod() const { return signatureMethod; }

  void setSignatureMethod(std::string input_signatureMethod) {
    signatureMethod = input_signatureMethod;
  }

  std::string getAuthChannel() const { return authChannel; }

  void setAuthChannel(std::string input_channel) { authChannel = input_channel; }

  bool isValid() const {
    if (accessKey.empty() || secretKey.empty() || authChannel.empty())
      return false;

    return true;
  }

 private:
  std::string accessKey;
  std::string secretKey;
  std::string signature;
  std::string signatureMethod;
  std::string authChannel;
};
}
#endif
