---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

## testing value

- name: test-value 1 - set "state=present" and "value=null" and "allow_no_value=false" and fail
  ini_file:
    path: "{{ output_file }}"
    section: cars
    option: audi
    value: null
    allow_no_value: false
  register: result_value_1
  ignore_errors: true

- name: test-value 1 - verify error message
  assert:
    that:
      - result_value_1 is not changed
      - result_value_1 is failed
      - result_value_1.msg == "Parameter 'value(s)' must be defined if state=present and allow_no_value=False."


- name: test-value 2 - set "state=present" and omit "value" and "allow_no_value=false" and fail
  ini_file:
    path: "{{ output_file }}"
    section: cars
    option: audi
    allow_no_value: false
  register: result_value_2
  ignore_errors: true

- name: test-value 2 - verify error message
  assert:
    that:
      - result_value_2 is not changed
      - result_value_2 is failed
      - result_value_2.msg == "Parameter 'value(s)' must be defined if state=present and allow_no_value=False."


- name: test-value 3 - add "fav=lemonade" in section "[drinks]" in specified file
  ini_file:
    path: "{{ output_file }}"
    section: drinks
    option: fav
    value: lemonade
  register: result3

- name: test-value 3 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 3 - set expected content and get current ini file content
  set_fact:
    expected3: |

      [drinks]
      fav = lemonade
    content3: "{{ output_content.content | b64decode }}"

- name: test-value 3 - Verify content of ini file is as expected and ini_file 'changed' is true
  assert:
    that:
      - result3 is changed
      - result3.msg == 'section and option added'
      - content3 == expected3


- name: test-value 4 - add "fav=lemonade" is in section "[drinks]" again
  ini_file:
    path: "{{ output_file }}"
    section: drinks
    option: fav
    value: lemonade
  register: result4

- name: test-value 4 - Ensure unchanged
  assert:
    that:
      - result4 is not changed
      - result4.msg == 'OK'


- name: test-value 5 - Ensure "beverage=coke" is in section "[drinks]"
  ini_file:
    path: "{{ output_file }}"
    section: drinks
    option: beverage
    value: coke
  register: result5

- name: test-value 5 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 5 - set expected content and get current ini file content
  set_fact:
    expected5: |

      [drinks]
      fav = lemonade
      beverage = coke
    content5: "{{ output_content.content | b64decode }}"

- name: test-value 5 - assert 'changed' is true and content is OK
  assert:
    that:
      - result5 is changed
      - result5.msg == 'option added'
      - content5 == expected5


- name: test-value 6 - Remove option "beverage=coke"
  ini_file:
    path: "{{ output_file }}"
    section: drinks
    option: beverage
    state: absent
  register: result6

- name: test-value 6 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 6 - set expected content and get current ini file content
  set_fact:
    expected6: |

      [drinks]
      fav = lemonade
    content6: "{{ output_content.content | b64decode }}"

- name: test-value 6 - assert 'changed' is true and content is as expected
  assert:
    that:
      - result6 is changed
      - result6.msg == 'option changed'
      - content6 == expected6


- name: test-value 7 - remove section 'drinks'
  ini_file:
    path: "{{ output_file }}"
    section: drinks
    state: absent
  register: result7

- name: test-value 7 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 7 - get current ini file content
  set_fact:
    content7: "{{ output_content.content | b64decode }}"

- name: test-value 7 - assert 'changed' is true and content is empty
  assert:
    that:
      - result7 is changed
      - result7.msg == 'section removed'
      - content7 == "\n"


# allow_no_value

- name: test-value 8 - test allow_no_value
  ini_file:
    path: "{{ output_file }}"
    section: mysqld
    option: skip-name
    allow_no_value: true
  register: result8

- name: test-value 8 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 8 - set expected content and get current ini file content
  set_fact:
    content8: "{{ output_content.content | b64decode }}"
    expected8: |

      [mysqld]
      skip-name

- name: test-value 8 - assert 'changed' is true and section and option added
  assert:
    that:
      - result8 is changed
      - result8.msg == 'section and option added'
      - content8 == expected8


- name: test-value 9 - test allow_no_value idempotency
  ini_file:
    path: "{{ output_file }}"
    section: mysqld
    option: skip-name
    allow_no_value: true
  register: result9

- name: test-value 9 - assert 'changed' is false
  assert:
    that:
      - result9 is not changed
      - result9.msg == 'OK'


- name: test-value 10 - test create empty section
  ini_file:
    path: "{{ output_file }}"
    section: new_empty_section
    allow_no_value: true
  register: result10

- name: test-value 10 - assert 'changed' is true and section added
  assert:
    that:
      - result10 is changed
      - result10.msg == 'only section added'


- name: test-value 11 - test create empty section idempotency
  ini_file:
    path: "{{ output_file }}"
    section: new_empty_section
    allow_no_value: true
  register: result11

- name: test-value 11 - assert 'changed' is false
  assert:
    that:
      - result11 is not changed
      - result11.msg == 'OK'


- name: test-value 12 - test remove empty section
  ini_file:
    state: absent
    path: "{{ output_file }}"
    section: new_empty_section
    allow_no_value: true

- name: test-value 12 - test allow_no_value with loop
  ini_file:
    path: "{{ output_file }}"
    section: mysqld
    option: "{{ item.o }}"
    value: "{{ item.v | d(omit) }}"
    allow_no_value: true
  loop:
    - { o: "skip-name-resolve" }
    - { o: "max_connections", v: "500" }

- name: test-value 12 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 12 - set expected content and get current ini file content
  set_fact:
    content12: "{{ output_content.content | b64decode }}"
    expected12: |

      [mysqld]
      skip-name
      skip-name-resolve
      max_connections = 500
  
- name: test-value 12 - Verify content of ini file is as expected
  assert:
    that:
      - content12 == expected12


- name: test-value 13 - change option with no value to option with value
  ini_file:
    path: "{{ output_file }}"
    section: mysqld
    option: skip-name
    value: myvalue
  register: result13

- name: test-value 13 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 13 - set expected content and get current ini file content
  set_fact:
    content13: "{{ output_content.content | b64decode }}"
    expected13: |

      [mysqld]
      skip-name = myvalue
      skip-name-resolve
      max_connections = 500

- name: test-value 13 - assert 'changed' and msg 'option changed' and content is as expected
  assert:
    that:
      - result13 is changed
      - result13.msg == 'option changed'
      - content13 == expected13


- name: test-value 14 - change option with value to option with no value
  ini_file:
    path: "{{ output_file }}"
    section: mysqld
    option: skip-name
    allow_no_value: true
  register: result14

- name: test-value 14 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 14 - set expected content and get current ini file content
  set_fact:
    content14: "{{ output_content.content | b64decode }}"
    expected14: |

      [mysqld]
      skip-name
      skip-name-resolve
      max_connections = 500

- name: test-value 14 - assert 'changed' is true and msg 'option changed' and content is as expected
  assert:
    that:
      - result14 is changed
      - result14.msg == 'option changed'
      - content14 == expected14


- name: test-value 15 - Remove option with no value
  ini_file:
    path: "{{ output_file }}"
    section: mysqld
    option: skip-name-resolve
    state: absent
  register: result15

- name: test-value 15 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 15 - set expected content and get current ini file content
  set_fact:
    content15: "{{ output_content.content | b64decode }}"
    expected15: |

      [mysqld]
      skip-name
      max_connections = 500

- name: test-value 15 - assert 'changed' is true and msg 'option changed' and content is as expected
  assert:
    that:
      - result15 is changed
      - result15.msg == 'option changed'
      - content15 == expected15


- name: test-value 16 - Clean test file
  copy:
    content: ""
    dest: "{{ output_file }}"
    force: true

- name: test-value 16 - Ensure "beverage=coke" is created within no section
  ini_file:
    section:
    path: "{{ output_file }}"
    option: beverage
    value: coke
  register: result16

- name: test-value 16 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 16 - set expected content and get current ini file content
  set_fact:
    expected16: |+
      beverage = coke
      
    content16: "{{ output_content.content | b64decode }}"

- name: test-value 16 - assert 'changed' is true and content is OK (no section)
  assert:
    that:
      - result16 is changed
      - result16.msg == 'option added'
      - content16 == expected16


- name: test-value 17 - Ensure "beverage=coke" is modified as "beverage=water" within no section
  ini_file:
    path: "{{ output_file }}"
    option: beverage
    value: water
    section:
  register: result17

- name: test-value 17 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 17 - set expected content and get current ini file content
  set_fact:
    expected17: |+
      beverage = water
      
    content17: "{{ output_content.content | b64decode }}"

- name: test-value 17 - assert 'changed' is true and content is OK (no section)
  assert:
    that:
      - result17 is changed
      - result17.msg == 'option changed'
      - content17 == expected17


- name: test-value 18 - remove option 'beverage' within no section
  ini_file:
    section:
    path: "{{ output_file }}"
    option: beverage
    state: absent
  register: result18

- name: test-value 18 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 18 - get current ini file content
  set_fact:
    content18: "{{ output_content.content | b64decode }}"

- name: test-value 18 - assert 'changed' is true and option is removed (no section)
  assert:
    that:
      - result18 is changed
      - result18.msg == 'option changed'
      - content18 == "\n"


- name: test-value 19 - Check add option without section before existing section
  block:
    - name: test-value 19 - Add option with section
      ini_file:
        path: "{{ output_file }}"
        section: drinks
        option: beverage
        value: water
    - name: test-value 19 - Add option without section
      ini_file:
        path: "{{ output_file }}"
        section:
        option: like
        value: tea

- name: test-value 19 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 19 - set expected content and get current ini file content
  set_fact:
    expected19: |
      like = tea

      [drinks]
      beverage = water
    content19: "{{ output_content.content | b64decode }}"

- name: test-value 19 - Verify content of ini file is as expected
  assert:
    that:
      - content19 == expected19


- name: test-value 20 - Check add option with empty string value
  block:
    - name: test-value 20 - Remove drinks
      ini_file:
        path: "{{ output_file }}"
        section: drinks
        state: absent
    - name: test-value 20 - Remove tea
      ini_file:
        path: "{{ output_file }}"
        section:
        option: like
        value: tea
        state: absent
    # See https://github.com/ansible-collections/community.general/issues/3031
    - name: test-value 20 - Tests with empty strings
      ini_file:
        path: "{{ output_file }}"
        section: "{{ item.section | d('extensions') }}"
        option: "{{ item.option }}"
        value: ""
        allow_no_value: "{{ item.no_value | d(omit) }}"
      loop:
        - option: evolve
        - option: regress
        - section: foobar
          option: foo
          no_value: true
        - option: improve
          no_value: true

- name: test-value 20 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 20 - set expected content and get current ini file content
  set_fact:
    expected20: |+
      
      [extensions]
      evolve = 
      regress = 
      improve = 
      [foobar]
      foo = 
    content20: "{{ output_content.content | b64decode }}"

- name: test-value 20 - Verify content of ini file is as expected
  assert:
    that:
      - content20 == expected20


- name: test-value 21 - Create starting ini file
  copy:
    # The content below is the following text file with BOM:
    # [section1]
    # var1=aaa
    # var2=bbb
    # [section2]
    # var3=ccc
    content: !!binary |
      77u/W3NlY3Rpb24xXQp2YXIxPWFhYQp2YXIyPWJiYgpbc2VjdGlvbjJdCnZhcjM9Y2NjCg==
    dest: "{{ output_file }}"

- name: test-value 21 -  Test ini breakage
  ini_file:
    path: "{{ output_file }}"
    section: section1
    option: var4
    value: 0
  register: result21

- name: test-value 21 - read content from output file
  slurp:
    src: "{{ output_file }}"
  register: output_content

- name: test-value 21 - set expected content and get current ini file content
  set_fact:
    expected21: |
      [section1]
      var1=aaa
      var2=bbb
      var4 = 0
      [section2]
      var3=ccc
    content21: "{{ output_content.content | b64decode }}"

- name: test-value 21 - Verify content of ini file is as expected
  assert:
    that:
      - result21 is changed
      - result21.msg == 'option added'
      - content21 == expected21
