public static ParsedCommand parse(
          // CHECKSTYLE_RULES.ON: CyclomaticComplexity
          final String sql, final Map<String, String> variables) {

    validateSupportedStatementType(sql);
    final String substituted;
    try {
      substituted = VariableSubstitutor.substitute(KSQL_PARSER.parse(sql).get(0), variables);
    } catch (ParseFailedException e) {
      throw new MigrationException(String.format(
              "Failed to parse the statement. Statement: %s. Reason: %s",
              sql, e.getMessage()));
    }
    final SqlBaseParser.SingleStatementContext statementContext = KSQL_PARSER.parse(substituted)
            .get(0).getStatement();
    final boolean isStatement = StatementType.get(statementContext.statement().getClass())
            == StatementType.STATEMENT;
    return new ParsedCommand(substituted,
            isStatement ? Optional.empty() : Optional.of(new AstBuilder(TypeRegistry.EMPTY)
            .buildStatement(statementContext)));
  }
@Test
  public void shouldParseAssertSchema() {
    // Given:
    final String assertTopics = "assert schema id 3; assert not exists schema subject 'abcd' timeout 4 minutes;"
        + "assert schema subject ${subject} id ${id} timeout 10 seconds;";

    // When:
    List<CommandParser.ParsedCommand> commands = parse(assertTopics, ImmutableMap.of("subject", "name", "id", "4"));

    // Then:
    assertThat(commands.size(), is(3));
    assertThat(commands.get(0).getCommand(), is("assert schema id 3;"));
    assertThat(commands.get(0).getStatement().isPresent(), is (true));
    assertThat(commands.get(0).getStatement().get(), instanceOf(AssertSchema.class));
    assertThat(((AssertSchema) commands.get(0).getStatement().get()).getSubject(), is(Optional.empty()));
    assertThat(((AssertSchema) commands.get(0).getStatement().get()).getId().get(), is(3));
    assertThat(((AssertSchema) commands.get(0).getStatement().get()).checkExists(), is(true));
    assertThat(((AssertSchema) commands.get(0).getStatement().get()).getTimeout(), is(Optional.empty()));

    assertThat(commands.get(1).getCommand(), is( "assert not exists schema subject 'abcd' timeout 4 minutes;"));
    assertThat(commands.get(1).getStatement().isPresent(), is (true));
    assertThat(commands.get(1).getStatement().get(), instanceOf(AssertSchema.class));
    assertThat(((AssertSchema) commands.get(1).getStatement().get()).getSubject().get(), is("abcd"));
    assertThat(((AssertSchema) commands.get(1).getStatement().get()).getId(), is(Optional.empty()));
    assertThat(((AssertSchema) commands.get(1).getStatement().get()).checkExists(), is(false));
    assertThat(((AssertSchema) commands.get(1).getStatement().get()).getTimeout().get(), is(WindowTimeClause.of(4, TimeUnit.MINUTES.name())));

    assertThat(commands.get(2).getCommand(), is( "assert schema subject name id 4 timeout 10 seconds;"));
    assertThat(commands.get(2).getStatement().isPresent(), is (true));
    assertThat(commands.get(2).getStatement().get(), instanceOf(AssertSchema.class));
    assertThat(((AssertSchema) commands.get(2).getStatement().get()).getSubject().get(), is("name"));
    assertThat(((AssertSchema) commands.get(2).getStatement().get()).getId().get(), is(4));
    assertThat(((AssertSchema) commands.get(2).getStatement().get()).checkExists(), is(true));
    assertThat(((AssertSchema) commands.get(2).getStatement().get()).getTimeout().get(), is(WindowTimeClause.of(10, TimeUnit.SECONDS.name())));
  }