//
// Copyright (C) 2020 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.

#pragma once

#include "cuttlefish/host/commands/modem_simulator/modem_service.h"

namespace cuttlefish {

class SupService : public ModemService, public std::enable_shared_from_this<SupService> {
 public:
  SupService(int32_t service_id, ChannelMonitor* channel_monitor,
             ThreadLooper* thread_looper);
  ~SupService() = default;

  SupService(const SupService &) = delete;
  SupService &operator=(const SupService &) = delete;

  void HandleUSSD(const Client& client, std::string& command);
  void HandleCLIR(const Client& client, std::string& command);
  void HandleCallWaiting(const Client& client, std::string& command);
  void HandleCLIP(const Client& client);
  void HandleCallForward(const Client& client, std::string& command);
  void HandleSuppServiceNotifications(const Client& client, std::string& command);

 private:
  std::vector<CommandHandler> InitializeCommandHandlers();
  void InitializeServiceState();

  struct ClirStatusInfo {
    enum ClirType {
      DEFAULT = 0,                  // "use subscription default value"
      CLIR_INVOCATION        = 1,   // restrict CLI presentation
      CLIR_SUPPRESSION       = 2,   // allow CLI presentation
    };

    enum ClirStatus {
      CLIR_NOT_PROVISIONED         = 0,
      CLIR_PROVISIONED             = 1,
      UNKNOWN                       = 2,
      CLIR_PRESENTATION_RESTRICTED = 3,
      CLIR_PRESENTATION_ALLOWED    = 4,
    };

    ClirType type;
    ClirStatus status;
  };
  ClirStatusInfo clir_status_;

  struct CallForwardInfo {
    enum CallForwardInfoStatus {
      DISABLE       = 0,
      ENABLE        = 1,
      INTERROGATE   = 2,
      REGISTRATION  = 3,
      ERASURE       = 4,
    };

    enum Reason {
      CFU         = 0,  // communication forwarding unconditional
      CFB         = 1,  //communication forwarding on busy user
      CFNR        = 2,  // communication forwarding on no reply
      CFNRC       = 3,  // communication forwarding on subscriber not reachable
      ALL_CF      = 4,  // all call forwarding
      ALL_CONDITIONAL_CF = 5, //all conditional call forwarding
      CD          = 6,  // communication deflection
      CFNL        = 7,  // communication forwarding on not logged-in
    };

    CallForwardInfoStatus status;
    Reason reason;
    int number_type;    // From 27.007 +CCFC/+CLCK "class"
    int ton;            // "type" from TS 27.007 7.11
    std::string number; // "number" from TS 27.007 7.11. May be NULL
    int timeSeconds;    // for CF no reply only

    CallForwardInfo(Reason reason) :
      status(DISABLE), reason(reason), number_type(2), ton(129), number(""),
        timeSeconds(0){};
  };
  std::vector<CallForwardInfo> call_forward_infos_;

  struct CallWaitingInfo {
    int presentation_status;  // sets / shows the result code presentation status to the TE,
                              // 0: disable; 1: enable
    int mode;                 // 0: disable; 1: enable; 2: query status
    int classx;               // a sum of integers each representing a class of information
                              // default 7-voice, data and fax, see FacilityLock::Class

    CallWaitingInfo() :
      presentation_status(1), mode(0), classx(7) {};
  };
  CallWaitingInfo call_waiting_info_;
};

}  // namespace cuttlefish
