/*
 * 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.
 */

#ifndef SRC_PROFILING_MEMORY_HEAPPROFD_PRODUCER_H_
#define SRC_PROFILING_MEMORY_HEAPPROFD_PRODUCER_H_

#include <map>

#include "perfetto/base/task_runner.h"
#include "perfetto/tracing/core/basic_types.h"
#include "perfetto/tracing/core/producer.h"
#include "perfetto/tracing/core/tracing_service.h"
#include "src/profiling/memory/bounded_queue.h"
#include "src/profiling/memory/socket_listener.h"

namespace perfetto {
namespace profiling {

class HeapprofdProducer : public Producer {
 public:
  HeapprofdProducer(base::TaskRunner* task_runner);
  ~HeapprofdProducer() override;

  // Producer Impl:
  void OnConnect() override;
  void OnDisconnect() override;
  void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&) override;
  void StartDataSource(DataSourceInstanceID, const DataSourceConfig&) override;
  void StopDataSource(DataSourceInstanceID) override;
  void OnTracingSetup() override;
  void Flush(FlushRequestID,
             const DataSourceInstanceID* data_source_ids,
             size_t num_data_sources) override;

  // TODO(fmayer): Delete once we have generic reconnect logic.
  void ConnectWithRetries(const char* socket_name);

 private:
  // TODO(fmayer): Delete once we have generic reconnect logic.
  enum State {
    kNotStarted = 0,
    kNotConnected,
    kConnecting,
    kConnected,
  };
  void Connect();
  void Restart();
  void ResetConnectionBackoff();
  void IncreaseConnectionBackoff();

  // TODO(fmayer): Delete once we have generic reconnect logic.
  State state_ = kNotStarted;
  uint32_t connection_backoff_ms_ = 0;
  const char* socket_name_ = nullptr;

  std::function<void(UnwindingRecord)> MakeSocketListenerCallback();
  std::vector<BoundedQueue<UnwindingRecord>> MakeUnwinderQueues(size_t n);
  std::vector<std::thread> MakeUnwindingThreads(size_t n);
  std::unique_ptr<base::UnixSocket> MakeSocket();

  void FinishDataSourceFlush(FlushRequestID flush_id);
  bool Dump(DataSourceInstanceID id,
            FlushRequestID flush_id,
            bool has_flush_id);
  void DoContinuousDump(DataSourceInstanceID id, uint32_t dump_interval);

  struct DataSource {
    std::vector<pid_t> pids;
    // This is a shared ptr so we can lend a weak_ptr to the bookkeeping
    // thread for unwinding.
    std::shared_ptr<TraceWriter> trace_writer;
    // These are opaque handles that shut down the sockets in SocketListener
    // once they go away.
    std::vector<SocketListener::ProfilingSession> sessions;
  };

  std::map<DataSourceInstanceID, DataSource> data_sources_;
  std::map<FlushRequestID, size_t> flushes_in_progress_;

  // These two are borrowed from the caller.
  base::TaskRunner* const task_runner_;
  std::unique_ptr<TracingService::ProducerEndpoint> endpoint_;

  BoundedQueue<BookkeepingRecord> bookkeeping_queue_;
  BookkeepingThread bookkeeping_thread_;
  std::thread bookkeeping_th_;
  std::vector<BoundedQueue<UnwindingRecord>> unwinder_queues_;
  std::vector<std::thread> unwinding_threads_;
  SocketListener socket_listener_;
  std::unique_ptr<base::UnixSocket> socket_;

  base::WeakPtrFactory<HeapprofdProducer> weak_factory_;
};

}  // namespace profiling
}  // namespace perfetto

#endif  // SRC_PROFILING_MEMORY_HEAPPROFD_PRODUCER_H_
