/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/desktop_capture/mac/window_list_utils.h"

#include <ApplicationServices/ApplicationServices.h>

#include <algorithm>
#include <cmath>
#include <iterator>
#include <list>
#include <map>

#include "rtc_base/checks.h"

static_assert(static_cast<webrtc::WindowId>(kCGNullWindowID) ==
                  webrtc::kNullWindowId,
              "kNullWindowId needs to equal to kCGNullWindowID.");

namespace webrtc {

namespace {

bool ToUtf8(const CFStringRef str16, std::string* str8) {
  size_t maxlen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str16),
                                                    kCFStringEncodingUTF8) +
                  1;
  std::unique_ptr<char[]> buffer(new char[maxlen]);
  if (!buffer ||
      !CFStringGetCString(str16, buffer.get(), maxlen, kCFStringEncodingUTF8)) {
    return false;
  }
  str8->assign(buffer.get());
  return true;
}

// Get CFDictionaryRef from |id| and call |on_window| against it. This function
// returns false if native APIs fail, typically it indicates that the |id| does
// not represent a window. |on_window| will not be called if false is returned
// from this function.
bool GetWindowRef(CGWindowID id,
                  rtc::FunctionView<void(CFDictionaryRef)> on_window) {
  RTC_DCHECK(on_window);

  // TODO(zijiehe): |id| is a 32-bit integer, casting it to an array seems not
  // safe enough. Maybe we should create a new
  // const void* arr[] = {
  //   reinterpret_cast<void*>(id) }
  // };
  CFArrayRef window_id_array =
      CFArrayCreate(NULL, reinterpret_cast<const void**>(&id), 1, NULL);
  CFArrayRef window_array =
      CGWindowListCreateDescriptionFromArray(window_id_array);

  bool result = false;
  // TODO(zijiehe): CFArrayGetCount(window_array) should always return 1.
  // Otherwise, we should treat it as failure.
  if (window_array && CFArrayGetCount(window_array)) {
    on_window(reinterpret_cast<CFDictionaryRef>(
        CFArrayGetValueAtIndex(window_array, 0)));
    result = true;
  }

  if (window_array) {
    CFRelease(window_array);
  }
  CFRelease(window_id_array);
  return result;
}

}  // namespace

bool GetWindowList(rtc::FunctionView<bool(CFDictionaryRef)> on_window,
                   bool ignore_minimized) {
  RTC_DCHECK(on_window);

  // Only get on screen, non-desktop windows.
  // According to
  // https://developer.apple.com/documentation/coregraphics/cgwindowlistoption/1454105-optiononscreenonly
  // , when kCGWindowListOptionOnScreenOnly is used, the order of windows are in
  // decreasing z-order.
  CFArrayRef window_array = CGWindowListCopyWindowInfo(
      kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
      kCGNullWindowID);
  if (!window_array)
    return false;

  MacDesktopConfiguration desktop_config = MacDesktopConfiguration::GetCurrent(
      MacDesktopConfiguration::TopLeftOrigin);

  // Check windows to make sure they have an id, title, and use window layer
  // other than 0.
  CFIndex count = CFArrayGetCount(window_array);
  for (CFIndex i = 0; i < count; i++) {
    CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
        CFArrayGetValueAtIndex(window_array, i));
    if (!window) {
      continue;
    }

    CFNumberRef window_id = reinterpret_cast<CFNumberRef>(
        CFDictionaryGetValue(window, kCGWindowNumber));
    if (!window_id) {
      continue;
    }

    CFNumberRef window_layer = reinterpret_cast<CFNumberRef>(
        CFDictionaryGetValue(window, kCGWindowLayer));
    if (!window_layer) {
      continue;
    }

    // Skip windows with layer!=0 (menu, dock).
    int layer;
    if (!CFNumberGetValue(window_layer, kCFNumberIntType, &layer)) {
      continue;
    }
    if (layer != 0) {
      continue;
    }

    // Skip windows that are minimized and not full screen.
    if (ignore_minimized && !IsWindowOnScreen(window) &&
        !IsWindowFullScreen(desktop_config, window)) {
      continue;
    }

    // If window title is empty, only consider it if it is either on screen or
    // fullscreen.
    CFStringRef window_title = reinterpret_cast<CFStringRef>(
        CFDictionaryGetValue(window, kCGWindowName));
    if (!window_title && !IsWindowOnScreen(window) &&
        !IsWindowFullScreen(desktop_config, window)) {
      continue;
    }

    if (!on_window(window)) {
      break;
    }
  }

  CFRelease(window_array);
  return true;
}

bool GetWindowList(DesktopCapturer::SourceList* windows,
                   bool ignore_minimized) {
  // Use a std::list so that iterators are preversed upon insertion and
  // deletion.
  std::list<DesktopCapturer::Source> sources;
  std::map<int, std::list<DesktopCapturer::Source>::const_iterator> pid_itr_map;
  const bool ret = GetWindowList(
      [&sources, &pid_itr_map](CFDictionaryRef window) {
        WindowId window_id = GetWindowId(window);
        if (window_id != kNullWindowId) {
          const std::string title = GetWindowTitle(window);
          const int pid = GetWindowOwnerPid(window);
          // Check if window for the same pid have been already inserted.
          std::map<int,
                   std::list<DesktopCapturer::Source>::const_iterator>::iterator
              itr = pid_itr_map.find(pid);

          // Only consider empty titles if the app has no other window with a
          // proper title.
          if (title.empty()) {
            std::string owner_name = GetWindowOwnerName(window);

            // At this time we do not know if there will be other windows
            // for the same pid unless they have been already inserted, hence
            // the check in the map. Also skip the window if owner name is
            // empty too.
            if (!owner_name.empty() && (itr == pid_itr_map.end())) {
              sources.push_back(DesktopCapturer::Source{window_id, owner_name});
              RTC_DCHECK(!sources.empty());
              // Get an iterator on the last valid element in the source list.
              std::list<DesktopCapturer::Source>::const_iterator last_source =
                  --sources.end();
              pid_itr_map.insert(
                  std::pair<int,
                            std::list<DesktopCapturer::Source>::const_iterator>(
                      pid, last_source));
            }
          } else {
            sources.push_back(DesktopCapturer::Source{window_id, title});
            // Once the window with empty title has been removed no other empty
            // windows are allowed for the same pid.
            if (itr != pid_itr_map.end() && (itr->second != sources.end())) {
              sources.erase(itr->second);
              // sdt::list::end() never changes during the lifetime of that
              // list.
              itr->second = sources.end();
            }
          }
        }
        return true;
      },
      ignore_minimized);

  if (!ret)
    return false;

  RTC_DCHECK(windows);
  windows->reserve(windows->size() + sources.size());
  std::copy(std::begin(sources), std::end(sources),
            std::back_inserter(*windows));

  return true;
}

// Returns true if the window is occupying a full screen.
bool IsWindowFullScreen(const MacDesktopConfiguration& desktop_config,
                        CFDictionaryRef window) {
  bool fullscreen = false;
  CFDictionaryRef bounds_ref = reinterpret_cast<CFDictionaryRef>(
      CFDictionaryGetValue(window, kCGWindowBounds));

  CGRect bounds;
  if (bounds_ref &&
      CGRectMakeWithDictionaryRepresentation(bounds_ref, &bounds)) {
    for (MacDisplayConfigurations::const_iterator it =
             desktop_config.displays.begin();
         it != desktop_config.displays.end(); it++) {
      if (it->bounds.equals(
              DesktopRect::MakeXYWH(bounds.origin.x, bounds.origin.y,
                                    bounds.size.width, bounds.size.height))) {
        fullscreen = true;
        break;
      }
    }
  }

  return fullscreen;
}

bool IsWindowOnScreen(CFDictionaryRef window) {
  CFBooleanRef on_screen = reinterpret_cast<CFBooleanRef>(
      CFDictionaryGetValue(window, kCGWindowIsOnscreen));
  return on_screen != NULL && CFBooleanGetValue(on_screen);
}

bool IsWindowOnScreen(CGWindowID id) {
  bool on_screen;
  if (GetWindowRef(id, [&on_screen](CFDictionaryRef window) {
        on_screen = IsWindowOnScreen(window);
      })) {
    return on_screen;
  }
  return false;
}

std::string GetWindowTitle(CFDictionaryRef window) {
  CFStringRef title = reinterpret_cast<CFStringRef>(
      CFDictionaryGetValue(window, kCGWindowName));
  std::string result;
  if (title && ToUtf8(title, &result)) {
    return result;
  }

  return std::string();
}

std::string GetWindowTitle(CGWindowID id) {
  std::string title;
  if (GetWindowRef(id, [&title](CFDictionaryRef window) {
        title = GetWindowTitle(window);
      })) {
    return title;
  }
  return std::string();
}

std::string GetWindowOwnerName(CFDictionaryRef window) {
  CFStringRef owner_name = reinterpret_cast<CFStringRef>(
      CFDictionaryGetValue(window, kCGWindowOwnerName));
  std::string result;
  if (owner_name && ToUtf8(owner_name, &result)) {
    return result;
  }
  return std::string();
}

std::string GetWindowOwnerName(CGWindowID id) {
  std::string owner_name;
  if (GetWindowRef(id, [&owner_name](CFDictionaryRef window) {
        owner_name = GetWindowOwnerPid(window);
      })) {
    return owner_name;
  }
  return std::string();
}

WindowId GetWindowId(CFDictionaryRef window) {
  CFNumberRef window_id = reinterpret_cast<CFNumberRef>(
      CFDictionaryGetValue(window, kCGWindowNumber));
  if (!window_id) {
    return kNullWindowId;
  }

  // Note: WindowId is 64-bit on 64-bit system, but CGWindowID is always 32-bit.
  // CFNumberGetValue() fills only top 32 bits, so we should use CGWindowID to
  // receive the window id.
  CGWindowID id;
  if (!CFNumberGetValue(window_id, kCFNumberIntType, &id)) {
    return kNullWindowId;
  }

  return id;
}

int GetWindowOwnerPid(CFDictionaryRef window) {
  CFNumberRef window_pid = reinterpret_cast<CFNumberRef>(
      CFDictionaryGetValue(window, kCGWindowOwnerPID));
  if (!window_pid) {
    return 0;
  }

  int pid;
  if (!CFNumberGetValue(window_pid, kCFNumberIntType, &pid)) {
    return 0;
  }

  return pid;
}

int GetWindowOwnerPid(CGWindowID id) {
  int pid;
  if (GetWindowRef(id, [&pid](CFDictionaryRef window) {
        pid = GetWindowOwnerPid(window);
      })) {
    return pid;
  }
  return 0;
}

float GetScaleFactorAtPosition(const MacDesktopConfiguration& desktop_config,
                               DesktopVector position) {
  // Find the dpi to physical pixel scale for the screen where the mouse cursor
  // is.
  for (auto it = desktop_config.displays.begin();
       it != desktop_config.displays.end(); ++it) {
    if (it->bounds.Contains(position)) {
      return it->dip_to_pixel_scale;
    }
  }
  return 1;
}

float GetWindowScaleFactor(CGWindowID id, DesktopSize size) {
  DesktopRect window_bounds = GetWindowBounds(id);
  float scale = 1.0f;

  if (!window_bounds.is_empty() && !size.is_empty()) {
    float scale_x = size.width() / window_bounds.width();
    float scale_y = size.height() / window_bounds.height();
    // Currently the scale in X and Y directions must be same.
    if ((std::fabs(scale_x - scale_y) <=
         std::numeric_limits<float>::epsilon() * std::max(scale_x, scale_y)) &&
        scale_x > 0.0f) {
      scale = scale_x;
    }
  }

  return scale;
}

DesktopRect GetWindowBounds(CFDictionaryRef window) {
  CFDictionaryRef window_bounds = reinterpret_cast<CFDictionaryRef>(
      CFDictionaryGetValue(window, kCGWindowBounds));
  if (!window_bounds) {
    return DesktopRect();
  }

  CGRect gc_window_rect;
  if (!CGRectMakeWithDictionaryRepresentation(window_bounds, &gc_window_rect)) {
    return DesktopRect();
  }

  return DesktopRect::MakeXYWH(gc_window_rect.origin.x, gc_window_rect.origin.y,
                               gc_window_rect.size.width,
                               gc_window_rect.size.height);
}

DesktopRect GetWindowBounds(CGWindowID id) {
  DesktopRect result;
  if (GetWindowRef(id, [&result](CFDictionaryRef window) {
        result = GetWindowBounds(window);
      })) {
    return result;
  }
  return DesktopRect();
}

}  // namespace webrtc
