// Copyright 2014 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 XCTest;
@import os.log;

static const CGFloat kStandardTimeOut = 60.0;

@interface FlutterUITests : XCTestCase
@property (strong) XCUIApplication *app;
@end

@implementation FlutterUITests

- (void)setUp {
    [super setUp];
    self.continueAfterFailure = NO;

    XCUIApplication *app = [[XCUIApplication alloc] init];
    [app launch];
    self.app = app;
}

- (void)testFullScreenColdPop {
    XCUIApplication *app = self.app;
    [self waitForAndTapElement:app.buttons[@"Full Screen (Cold)"]];
    XCTAssertTrue([app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut]);

    [self waitForAndTapElement:app.otherElements[@"Increment via Flutter"]];
    XCTAssertTrue([app.staticTexts[@"Button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]);

    // Back navigation.
    [app.buttons[@"POP"] tap];
    XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]);
}

- (void)testFullScreenWarm {
    XCUIApplication *app = self.app;

    [self waitForAndTapElement:app.buttons[@"Full Screen (Warm)"]];
    BOOL newPageAppeared = [app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut];
    if (!newPageAppeared) {
        // Sometimes, the element doesn't respond to the tap, it seems an XCUITest race condition where the tap happened
        // too soon. Trying to tap the element again.
        [self waitForAndTapElement:app.buttons[@"Full Screen (Warm)"]];
        newPageAppeared = [app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut];
    }
    XCTAssertTrue(newPageAppeared);

    [self waitForAndTapElement:app.otherElements[@"Increment via Flutter"]];
    XCTAssertTrue([app.staticTexts[@"Button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]);

    // Back navigation.
    [app.buttons[@"POP"] tap];
    XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]);
}

- (void)testFlutterViewWarm {
    XCUIApplication *app = self.app;

    [self waitForAndTapElement:app.buttons[@"Flutter View (Warm)"]];
    BOOL newPageAppeared = [app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut];
    if (!newPageAppeared) {
      // Sometimes, the element doesn't respond to the tap, it seems an XCUITest race condition where the tap happened
      // too soon. Trying to tap the element again.
      [self waitForAndTapElement:app.buttons[@"Flutter View (Warm)"]];
      newPageAppeared = [app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut];
      if (!newPageAppeared) {
        os_log(OS_LOG_DEFAULT, "%@", app.debugDescription);
      }
    }
    XCTAssertTrue(newPageAppeared);

    [self waitForAndTapElement:app.otherElements[@"Increment via Flutter"]];
    XCTAssertTrue([app.staticTexts[@"Button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]);

    // Back navigation.
    [app.buttons[@"POP"] tap];
    XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]);
}

- (void)testHybridViewWarm {
    XCUIApplication *app = self.app;

    [self waitForAndTapElement:app.buttons[@"Hybrid View (Warm)"]];

    XCTAssertTrue([app.staticTexts[@"Flutter button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut]);
    XCTAssertTrue(app.staticTexts[@"Platform button tapped 0 times."].exists);

    [self waitForAndTapElement:app.otherElements[@"Increment via Flutter"]];
    XCTAssertTrue([app.staticTexts[@"Flutter button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]);
    XCTAssertTrue(app.staticTexts[@"Platform button tapped 0 times."].exists);

    [app.buttons[@"Increment via iOS"] tap];
    XCTAssertTrue([app.staticTexts[@"Flutter button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]);
    XCTAssertTrue(app.staticTexts[@"Platform button tapped 1 time."].exists);

    // Back navigation.
    [app.navigationBars[@"Hybrid Flutter/Native"].buttons[@"Flutter iOS Demos Home"] tap];
    XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]);
}

- (void)testDualCold {
    XCUIApplication *app = self.app;

    [self waitForAndTapElement:app.buttons[@"Dual Flutter View (Cold)"]];

    // There are two marquees.
    XCUIElementQuery *marqueeQuery = [app.staticTexts matchingIdentifier:@"This is Marquee"];
    [self expectationForPredicate:[NSPredicate predicateWithFormat:@"count = 2"] evaluatedWithObject:marqueeQuery handler:nil];
    [self waitForExpectationsWithTimeout:30.0 handler:nil];

    // Back navigation.
    [app.navigationBars[@"Dual Flutter Views"].buttons[@"Flutter iOS Demos Home"] tap];
    XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]);
}

- (void)waitForAndTapElement:(XCUIElement *)element {
    NSPredicate *hittable = [NSPredicate predicateWithFormat:@"exists == YES AND hittable == YES"];
    [self expectationForPredicate:hittable evaluatedWithObject:element handler:nil];
    [self waitForExpectationsWithTimeout:30.0 handler:nil];
    [element tap];
}

@end
