---
setup:
  - requires:
      capabilities:
        - method: GET
          path: /_query/view
          capabilities: [view_index_abstraction]
      test_runner_features: capabilities
      reason: "ES|QL views introduced"

  - do:
      indices.create:
        index: test
        body:
          mappings:
            properties:
              content:
                type: keyword
              color:
                type: keyword
              animal:
                type: keyword
              id:
                type: integer
  - do:
      bulk:
        index: "test"
        refresh: true
        body:
          - { "index": { } }
          - { "content": "This is a brown fox", "color": "brown", "animal": "fox", "id": 1 }
          - { "index": { } }
          - { "content": "This is a brown dog", "color": "brown", "animal": "dog", "id": 2 }
          - { "index": { } }
          - { "content": "This dog is really white", "color": "white", "animal": "dog", "id": 3 }
          - { "index": { } }
          - { "content": "The dog is brown but this document is very very long", "color": "brown", "animal": "dog", "id": 4 }
          - { "index": { } }
          - { "content": "There is also a white cat", "color": "white", "animal": "cat", "id": 5 }
          - { "index": { } }
          - { "content": "The quick brown fox jumps over the lazy dog", "color": "brown", "animal": "dog", "id": 6 }

---
"crud":
  - do:
      esql.put_view:
        name: dogs
        body:
          query: 'FROM test | WHERE animal == "dog"'

  - do:
      esql.get_view:
        name: dogs

  - match: { views.0.name: "dogs" }
  - match: { views.0.query: 'FROM test | WHERE animal == "dog"' }

  - do:
      esql.get_view: { }

  - match: { views.0.name: "dogs" }
  - match: { views.0.query: 'FROM test | WHERE animal == "dog"' }
  - length: { views: 1 }

  - do:
      esql.put_view:
        name: dogs
        body:
          query: 'FROM test | WHERE animal == "pooch"'

  - do:
      esql.get_view:
        name: dogs

  - match: { views.0.name: "dogs" }
  - match: { views.0.query: 'FROM test | WHERE animal == "pooch"' }
  - length: { views: 1 }

  - do:
      esql.delete_view:
        name: dogs

  - do:
      esql.get_view: { }

  - match: { views: [] }
  - length: { views: 0 }

---
"invalid-views":
  - do:
      catch: /invalid view name/
      esql.put_view:
        name: " "
        body:
          query: 'FROM test | WHERE animal == "dog"'

  - do:
      catch: /invalid view name/
      esql.put_view:
        name: "dogs#pants"
        body:
          query: 'FROM test | WHERE animal == "dog"'

  - do:
      catch: /invalid view name/
      esql.put_view:
        name: "dogsPants"
        body:
          query: 'FROM test | WHERE animal == "dog"'

  - do:
      catch: /Required \[query\]/
      esql.put_view:
        name: dogs
        body: {}

  - do:
      catch: /view query is missing or empty/
      esql.put_view:
        name: dogs
        body:
          query: ' '

  - do:
      catch: /mismatched input 'FRO'/
      esql.put_view:
        name: dogs
        body:
          query: 'FRO test'

  - do:
      esql.get_view: { }

  - match: { views: [] }

  - do:
      catch: missing
      esql.get_view:
        name: dogs

  - do:
      catch: /view \[dogs\] not found/
      esql.delete_view:
        name: dogs

---
"view-name-conflicts":
  - skip:
      features: allowed_warnings

  - do:
      indices.create:
        index: myindex

  - do:
      indices.put_alias:
        index: myindex
        name: myalias

  - do:
      allowed_warnings:
        - "index template [mytemplate] has index patterns [mydatastream] matching patterns from existing older templates [global] with patterns (global => [*]); this template [mytemplate] will take precedence during new index creation"
      indices.put_index_template:
        name: mytemplate
        body:
          index_patterns: [mydatastream]
          data_stream: {}

  - do:
      indices.create_data_stream:
        name: mydatastream

  - do:
      indices.put_alias:
        index: mydatastream
        name: mydatastreamalias

  - do:
      catch: /view \[myindex\] cannot be created, an existing concrete index with that name is present/
      esql.put_view:
        name: myindex
        body:
          query: 'FROM test | WHERE animal == "dog"'

  - do:
      catch: /view \[myalias\] cannot be created, an existing alias with that name is present/
      esql.put_view:
        name: myalias
        body:
          query: 'FROM test | WHERE animal == "dog"'

  - do:
      catch: /view \[mydatastream\] cannot be created, an existing data_stream with that name is present/
      esql.put_view:
        name: mydatastream
        body:
          query: 'FROM test | WHERE animal == "dog"'

  - do:
      catch: /view \[mydatastreamalias\] cannot be created, an existing alias with that name is present/
      esql.put_view:
        name: mydatastreamalias
        body:
          query: 'FROM test | WHERE animal == "dog"'

---
"abstraction-name-conflicts":
  - skip:
      features: allowed_warnings

  - do:
      esql.put_view:
        name: myview
        body:
          query: 'FROM test | WHERE animal == "dog"'

  - do:
      catch: /Invalid index name \[myview\], already exists as an ESQL view/
      indices.create:
        index: myview

  - do:
      indices.create:
        index: myindex

  - do:
      catch: /Invalid alias name \[myview\]. an index, data stream, or ESQL view exists with the same name as the alias/
      indices.put_alias:
        index: myindex
        name: myview

  - do:
      catch: /Invalid index name \[myview\], already exists as an ESQL view/
      indices.clone:
        index: myindex
        target: myview

  - do:
      allowed_warnings:
        - "index template [mytemplate] has index patterns [myvie*] matching patterns from existing older templates [global] with patterns (global => [*]); this template [mytemplate] will take precedence during new index creation"
      indices.put_index_template:
        name: mytemplate
        body:
          index_patterns: [myvie*]
          data_stream: {}

  - do:
      catch: /data_stream \[myview\] already exists as an ESQL view/
      indices.create_data_stream:
        name: myview

  - do:
      indices.create_data_stream:
        name: myviewds

  - do:
      catch: /Invalid alias name \[myview\]. an index, data stream, or ESQL view exists with the same name as the alias/
      indices.put_alias:
        index: myviewds
        name: myview

---
"invalid-operations":
  - skip:
      features: allowed_warnings

  - do:
      esql.put_view:
        name: myview
        body:
          query: 'FROM test | WHERE animal == "dog"'

  - do:
      search:
        index: myview
        body: { query: { match_all: {} } }

  - length: { hits.hits: 0 }

  - do:
      catch: /an ESQL view \[myview\] may not be the target of an index operation/
      index:
        index: myview
        id: "1"
        body: { "foo": "bar" }

  - do:
      index:
        index: myotherindex
        id: "1"
        body: { "foo": "bar" }
  - do:
      indices.refresh:
        index: myotherindex

  - do:
      search:
        index: my*
        expand_wildcards: [ all ]
        body: { query: { match_all: {} } }

  - length: { hits.hits: 1 }
