// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <Foundation/Foundation.h>
#import <Metal/Metal.h>
#import <OCMock/OCMock.h>

#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h"
#import "flutter/testing/testing.h"

@interface FlutterViewMockProvider : NSObject <FlutterViewProvider> {
  FlutterView* _implicitView;
}
/**
 * Create a FlutterViewMockProvider with the provided view as the implicit view.
 */
- (nonnull instancetype)initWithImplicitView:(nonnull FlutterView*)view;
@end

@implementation FlutterViewMockProvider

- (nonnull instancetype)initWithImplicitView:(nonnull FlutterView*)view {
  self = [super init];
  if (self != nil) {
    _implicitView = view;
  }
  return self;
}

- (nullable FlutterView*)viewForId:(FlutterViewId)viewId {
  if (viewId == kFlutterImplicitViewId) {
    return _implicitView;
  }
  return nil;
}

@end

namespace flutter::testing {
namespace {

typedef void (^PresentBlock)(NSArray<FlutterSurfacePresentInfo*>*);

id<FlutterViewProvider> MockViewProvider(PresentBlock onPresent = nil) {
  FlutterView* viewMock = OCMClassMock([FlutterView class]);
  FlutterSurfaceManager* surfaceManagerMock = OCMClassMock([FlutterSurfaceManager class]);
  FlutterSurface* surfaceMock = OCMClassMock([FlutterSurface class]);
  __block id<MTLTexture> textureMock = OCMProtocolMock(@protocol(MTLTexture));

  OCMStub([viewMock surfaceManager]).andReturn(surfaceManagerMock);

  OCMStub([surfaceManagerMock surfaceForSize:CGSize{}])
      .ignoringNonObjectArgs()
      .andDo(^(NSInvocation* invocation) {
        CGSize size;
        [invocation getArgument:&size atIndex:2];
        OCMStub([textureMock width]).andReturn(size.width);
        OCMStub([textureMock height]).andReturn(size.height);
      })
      .andReturn(surfaceMock);

  FlutterMetalTexture texture = {
      .struct_size = sizeof(FlutterMetalTexture),
      .texture_id = 1,
      .texture = (__bridge void*)textureMock,
      .user_data = (__bridge void*)surfaceMock,
      .destruction_callback = nullptr,
  };

  OCMStub([surfaceManagerMock present:[OCMArg any] notify:[OCMArg any]])
      .andDo(^(NSInvocation* invocation) {
        NSArray<FlutterSurfacePresentInfo*>* info;
        [invocation getArgument:&info atIndex:2];
        if (onPresent != nil) {
          onPresent(info);
        }
      });

  OCMStub([surfaceMock asFlutterMetalTexture]).andReturn(texture);

  return [[FlutterViewMockProvider alloc] initWithImplicitView:viewMock];
}
}  // namespace

TEST(FlutterCompositorTest, TestCreate) {
  std::unique_ptr<flutter::FlutterCompositor> macos_compositor =
      std::make_unique<FlutterCompositor>(MockViewProvider(),
                                          /*platform_view_controller*/ nullptr);

  FlutterBackingStore backing_store;
  FlutterBackingStoreConfig config;
  config.struct_size = sizeof(FlutterBackingStoreConfig);
  config.size.width = 800;
  config.size.height = 600;
  macos_compositor->CreateBackingStore(&config, &backing_store);

  ASSERT_EQ(backing_store.type, kFlutterBackingStoreTypeMetal);
  ASSERT_NE(backing_store.metal.texture.texture, nil);
  id<MTLTexture> texture = (__bridge id<MTLTexture>)backing_store.metal.texture.texture;
  ASSERT_EQ(texture.width, 800ul);
  ASSERT_EQ(texture.height, 600ul);
}

TEST(FlutterCompositorTest, TestPresent) {
  __block NSArray<FlutterSurfacePresentInfo*>* presentedSurfaces = nil;

  auto onPresent = ^(NSArray<FlutterSurfacePresentInfo*>* info) {
    presentedSurfaces = info;
  };

  std::unique_ptr<flutter::FlutterCompositor> macos_compositor =
      std::make_unique<FlutterCompositor>(MockViewProvider(onPresent),
                                          /*platform_view_controller*/ nullptr);

  FlutterBackingStore backing_store;
  FlutterBackingStoreConfig config;
  config.struct_size = sizeof(FlutterBackingStoreConfig);
  config.size.width = 800;
  config.size.height = 600;
  macos_compositor->CreateBackingStore(&config, &backing_store);

  FlutterLayer layers[] = {{
      .struct_size = sizeof(FlutterLayer),
      .type = kFlutterLayerContentTypeBackingStore,
      .backing_store = &backing_store,
      .offset = {0, 0},
      .size = {800, 600},
  }};
  const FlutterLayer* layers_ptr = layers;

  macos_compositor->Present(kFlutterImplicitViewId, &layers_ptr, 1);

  ASSERT_EQ(presentedSurfaces.count, 1ul);
}

}  // namespace flutter::testing
