text: /*
   * Copyright (c) 2019, Arm Limited and affiliates.
   * SPDX-License-Identifier: Apache-2.0
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #include "gtest/gtest.h"
  #include "ATCmdParser.h"
  #include <string.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <stdarg.h>
  #include "FileHandle_stub.h"
  #include "mbed_poll_stub.h"
  
  using namespace mbed;
  
  static bool expected_oob_callback = false;
  
  void urc_callback()
  {
      EXPECT_TRUE(expected_oob_callback);
  }
  
  
  // AStyle ignored as the definition is not clear due to preprocessor usage
  // *INDENT-OFF*
  class test_ATCmdParser : public testing::Test {
  protected:
  
      void SetUp()
      {
          filehandle_stub_short_value_counter = 0;
      }
  
      void TearDown()
      {
      }
  };
  // *INDENT-ON*
  
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_create)
  {
      FileHandle_stub fh1;
  
      ATCmdParser *at = new ATCmdParser(&fh1, ",");
      at->set_delimiter("\r");
      at->set_timeout(5000);
      at->debug_on(1);
  
      delete at;
  
      at = new ATCmdParser(&fh1, "\r");
  
      EXPECT_TRUE(at != NULL);
      delete at;
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_set_timeout)
  {
      FileHandle_stub fh1;
  
      ATCmdParser at(&fh1, ",");
      at.set_timeout(8);
      at.set_timeout(80);
  }
  
  
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_process_oob)
  {
      FileHandle_stub fh1;
  
      ATCmdParser at(&fh1);
      at.set_timeout(10);
  
      at.process_oob();
  
      filehandle_stub_short_value_counter = 1;
      fh1.short_value = POLLIN;
      at.oob("s", &urc_callback);
      at.process_oob();
  
      filehandle_stub_short_value_counter = 2;
      at.process_oob();
  
      char buf[5] = {0};
      char table[] = "ssssssssssssssssssssssssssssssss\0";
      filehandle_stub_table = table;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      at.read(buf, 5);
  
      filehandle_stub_short_value_counter = 2;
      expected_oob_callback = true;
      at.process_oob();
      expected_oob_callback = false;
  
      filehandle_stub_table_pos = 0;
      at.read(buf, 5);
  
      filehandle_stub_short_value_counter = 1;
      expected_oob_callback = true;
      at.process_oob();
      expected_oob_callback = false;
  
      char table2[5];
      table2[0] = '\r';
      table2[1] = '\r';
      table2[2] = '\n';
      table2[3] = '\n';
      table2[4] = 0;
      filehandle_stub_table = table2;
  
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      at.read(buf, 1);
  
      filehandle_stub_short_value_counter = 1;
      at.process_oob();
  
      filehandle_stub_table = table;
  
      filehandle_stub_short_value_counter = 0;
      filehandle_stub_table_pos = 0;
      filehandle_stub_table = NULL;
  }
  
  
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_flush)
  {
      FileHandle_stub fh1;
  
      ATCmdParser at(&fh1, ",");
      filehandle_stub_short_value_counter = 1;
      fh1.short_value = POLLIN;
      at.flush();
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_write)
  {
      FileHandle_stub fh1;
  
      ATCmdParser at(&fh1, ",");
      fh1.size_value = -1;
      EXPECT_TRUE(-1 == at.write("help", 4));
  
      mbed_poll_stub::revents_value = POLLOUT;
      mbed_poll_stub::int_value = 1;
      fh1.size_value = -1;
      EXPECT_TRUE(-1 == at.write("help", 4));
  
      mbed_poll_stub::revents_value = POLLOUT;
      mbed_poll_stub::int_value = 1;
      fh1.size_value = 7;
      EXPECT_EQ(4, at.write("help", 4));
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_set_delimiter)
  {
      FileHandle_stub fh1;
  
      ATCmdParser at(&fh1, ",");
      at.set_delimiter("+");
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_read)
  {
      FileHandle_stub fh1;
      filehandle_stub_table = NULL;
      filehandle_stub_table_pos = 0;
  
      ATCmdParser at(&fh1, ",");
      char buf[8] = {0};
      
  
      // TEST EMPTY BUFFER
      // Shouldn't read any byte since buffer is empty
      EXPECT_TRUE(-1 == at.read(buf, 1));
      // Return error due to error set to at handler by the above call on empty buffer
      EXPECT_TRUE(-1 == at.read(buf, 1));
  
      // TEST DATA IN BUFFER
      char table1[] = "1234512345678OK\r\n\0";
      filehandle_stub_table = table1;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
  
      // Read 5 bytes
      EXPECT_EQ(5, at.read(buf, 5));
      EXPECT_TRUE(!memcmp(buf, table1, 5));
      // get_char triggered above should have filled in the whole reading buffer
      EXPECT_EQ(filehandle_stub_table_pos, (strlen(buf)));
      // Read another 8 bytes
      EXPECT_TRUE(8 == at.read(buf, 8) && !memcmp(buf, table1 + 5, 8));
      // Reading more than the 4 bytes left -> ERROR
      EXPECT_EQ(-1, at.read(buf, 5));
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_debug_on)
  {
      FileHandle_stub fh1;
  
      ATCmdParser at(&fh1, ",");
      at.debug_on(true);
      at.debug_on(false);
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_abort)
  {
      FileHandle_stub fh1;
  
      ATCmdParser at(&fh1, ",");
      at.abort();
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_printf)
  {
      FileHandle_stub fh1;
  
      ATCmdParser at(&fh1);
      at.flush();
      at.debug_on(true);
  
      const char * format = "TEST %d %s %x %c TEST \r\r\n\n";
      mbed_poll_stub::revents_value = POLLOUT;
      mbed_poll_stub::int_value = 1;
      fh1.size_value = 64;
  
      EXPECT_EQ(22, at.printf(format, 5, "t", 0x5, 't'));
  
      fh1.size_value = -1;
      EXPECT_EQ(-1, at.printf(format, 5, "t", 0x5, 't'));
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_send)
  {
      FileHandle_stub fh1;
  
      ATCmdParser at(&fh1);
      at.flush();
      at.debug_on(true);
  
      const char * format = "TEST %d %s %x %c TEST \r\r\n\n";
      mbed_poll_stub::revents_value = POLLOUT;
      mbed_poll_stub::int_value = 1;
      fh1.size_value = 64;
  
      //VALID printf
      EXPECT_TRUE(at.send(format, 5, "t", 0x5, 't'));
      EXPECT_TRUE(at.send(""));
  
      fh1.size_value = -1;
      EXPECT_FALSE(at.send(format, 5, "t", 0x5, 't'));
      EXPECT_FALSE(at.send(""));
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_recv)
  {
      FileHandle_stub fh1;
      ATCmdParser at(&fh1, "\r", 8);
  
      //parse valid char
      char table1[] = "s";
      at.flush();
      filehandle_stub_table = table1;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      char c;
      EXPECT_TRUE(at.recv("%c", &c));
      EXPECT_EQ(c, 's');
  
      //too large response
      char table2[] = "1234567890\n";
      at.flush();
      filehandle_stub_table = table2;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      EXPECT_FALSE(at.recv("123456789%c\n", &c));
  
      //back to normal buffer
      ATCmdParser at1(&fh1);
      at1.flush();
      filehandle_stub_table = table2;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      EXPECT_TRUE(at1.recv("123456789%c\n", &c));
  
      char table3[] = "s\r\n\0";
      at1.flush();
      filehandle_stub_table = table3;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      EXPECT_TRUE(at.recv("%c", &c));
      EXPECT_EQ(c, 's');
  
      char table4[] = "s 1 E test\r\n";
      char text[5];
      int hexval;
      int intval;
      at1.flush();
      filehandle_stub_table = table4;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      EXPECT_TRUE(at1.recv("%c %d %x %s", &c, &intval, &hexval, &text));
      EXPECT_EQ(c, 's');
      EXPECT_EQ(intval, 1);
      EXPECT_EQ(hexval, 0xE);
      EXPECT_EQ(!memcmp(text, "test", 4), 0);
  
      char table5[] = "s 1 E test\r\nt 2 F tes2\r\n";
      char c1;
      char text1[5];
      int hexval1;
      int intval1;
      at1.flush();
      filehandle_stub_table = table5;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
  
      expected_oob_callback = true;
      at1.oob("s", &urc_callback);
      EXPECT_TRUE(at1.recv("%c %d %x %s\r\n%c %d %x %s\r\n", &c, &intval, &hexval, &text, &c, &intval, &hexval, &text));
      expected_oob_callback = false;
      EXPECT_EQ(c, 't');
      EXPECT_EQ(intval, 2);
      EXPECT_EQ(hexval, 0xF);
      EXPECT_EQ(memcmp(text, "tes2", 4), 0);
  
  }
  
  TEST_F(test_ATCmdParser, test_ATCmdParser_scanf)
  {
      FileHandle_stub fh1;
      ATCmdParser at(&fh1, "\r");
  
      //parse valid char
      char table1[] = "s";
      at.flush();
      filehandle_stub_table = table1;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      char c;
      EXPECT_TRUE(at.scanf("%c", &c));
      EXPECT_EQ(c, 's');
  
      //back to normal buffer
      char table2[] = "1234567890\n";
      at.flush();
      filehandle_stub_table = table2;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      EXPECT_TRUE(at.scanf("123456789%c\n", &c));
  
      char table3[] = "s\r\n\0";
      at.flush();
      filehandle_stub_table = table3;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      EXPECT_TRUE(at.scanf("%c", &c));
      EXPECT_EQ(c, 's');
  
      char table4[] = "s 1 E test\r\n";
      char text[5];
      memset(text, 0, 5);
      int hexval;
      int intval;
      at.flush();
      filehandle_stub_table = table4;
      filehandle_stub_table_pos = 0;
      mbed_poll_stub::revents_value = POLLIN;
      mbed_poll_stub::int_value = 1;
      EXPECT_TRUE(at.scanf("%c %d %x %s", &c, &intval, &hexval, &text));
      EXPECT_EQ(c, 's');
      EXPECT_EQ(intval, 1);
      EXPECT_EQ(hexval, 0xE);
      EXPECT_EQ(!memcmp(text, "test", 4), 0);
  
  }
  
  
  