/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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 "wear_ui.h"

#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <string>
#include <vector>

#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include <minui/minui.h>

#include "common.h"
#include "device.h"

// Return the current time as a double (including fractions of a second).
static double now() {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return tv.tv_sec + tv.tv_usec / 1000000.0;
}

WearRecoveryUI::WearRecoveryUI()
    : kProgressBarBaseline(RECOVERY_UI_PROGRESS_BAR_BASELINE),
      kMenuUnusableRows(RECOVERY_UI_MENU_UNUSABLE_ROWS) {
  // TODO: kMenuUnusableRows should be computed based on the lines in draw_screen_locked().

  // TODO: The following three variables are likely not needed. The first two are detected
  // automatically in ScreenRecoveryUI::LoadAnimation(), based on the actual files seen on device.
  intro_frames = 22;
  loop_frames = 60;

  touch_screen_allowed_ = true;

  for (size_t i = 0; i < 5; i++) backgroundIcon[i] = NULL;
}

int WearRecoveryUI::GetProgressBaseline() const {
  return kProgressBarBaseline;
}

// Draw background frame on the screen.  Does not flip pages.
// Should only be called with updateMutex locked.
// TODO merge drawing routines with screen_ui
void WearRecoveryUI::draw_background_locked() {
  pagesIdentical = false;
  gr_color(0, 0, 0, 255);
  gr_fill(0, 0, gr_fb_width(), gr_fb_height());

  if (currentIcon != NONE) {
    GRSurface* surface;
    if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
      if (!intro_done) {
        surface = introFrames[current_frame];
      } else {
        surface = loopFrames[current_frame];
      }
    } else {
      surface = backgroundIcon[currentIcon];
    }

    int width = gr_get_width(surface);
    int height = gr_get_height(surface);

    int x = (gr_fb_width() - width) / 2;
    int y = (gr_fb_height() - height) / 2;

    gr_blit(surface, 0, 0, width, height, x, y);
  }
}

static const char* SWIPE_HELP[] = {
  "Swipe up/down to move.",
  "Swipe left/right to select.",
  "",
  NULL
};

// TODO merge drawing routines with screen_ui
void WearRecoveryUI::draw_screen_locked() {
  char cur_selection_str[50];

  draw_background_locked();
  if (!show_text) {
    draw_foreground_locked();
  } else {
    SetColor(TEXT_FILL);
    gr_fill(0, 0, gr_fb_width(), gr_fb_height());

    int y = kMarginHeight;
    int x = kMarginWidth;
    if (show_menu) {
      std::string recovery_fingerprint =
          android::base::GetProperty("ro.bootimage.build.fingerprint", "");
      SetColor(HEADER);
      y += DrawTextLine(x + 4, y, "Android Recovery", true);
      for (auto& chunk : android::base::Split(recovery_fingerprint, ":")) {
        y += DrawTextLine(x + 4, y, chunk.c_str(), false);
      }

      // This is actually the help strings.
      y += DrawTextLines(x + 4, y, SWIPE_HELP);
      SetColor(HEADER);
      y += DrawTextLines(x + 4, y, menu_headers_);

      // Show the current menu item number in relation to total number if
      // items don't fit on the screen.
      if (menu_items > menu_end - menu_start) {
        sprintf(cur_selection_str, "Current item: %d/%d", menu_sel + 1, menu_items);
        gr_text(gr_sys_font(), x + 4, y, cur_selection_str, 1);
        y += char_height_ + 4;
      }

      // Menu begins here
      SetColor(MENU);

      for (int i = menu_start; i < menu_end; ++i) {
        if (i == menu_sel) {
          // draw the highlight bar
          SetColor(MENU_SEL_BG);
          gr_fill(x, y - 2, gr_fb_width() - x, y + char_height_ + 2);
          // white text of selected item
          SetColor(MENU_SEL_FG);
          if (menu_[i][0]) {
            gr_text(gr_sys_font(), x + 4, y, menu_[i], 1);
          }
          SetColor(MENU);
        } else if (menu_[i][0]) {
          gr_text(gr_sys_font(), x + 4, y, menu_[i], 0);
        }
        y += char_height_ + 4;
      }
      SetColor(MENU);
      y += 4;
      gr_fill(0, y, gr_fb_width(), y + 2);
      y += 4;
    }

    SetColor(LOG);

    // display from the bottom up, until we hit the top of the
    // screen, the bottom of the menu, or we've displayed the
    // entire text buffer.
    int ty;
    int row = (text_top_ + text_rows_ - 1) % text_rows_;
    size_t count = 0;
    for (int ty = gr_fb_height() - char_height_ - kMarginHeight; ty > y + 2 && count < text_rows_;
         ty -= char_height_, ++count) {
      gr_text(gr_sys_font(), x + 4, ty, text_[row], 0);
      --row;
      if (row < 0) row = text_rows_ - 1;
    }
  }
}

// TODO merge drawing routines with screen_ui
void WearRecoveryUI::update_progress_locked() {
  draw_screen_locked();
  gr_flip();
}

bool WearRecoveryUI::InitTextParams() {
  if (!ScreenRecoveryUI::InitTextParams()) {
    return false;
  }

  text_cols_ = (gr_fb_width() - (kMarginWidth * 2)) / char_width_;

  if (text_rows_ > kMaxRows) text_rows_ = kMaxRows;
  if (text_cols_ > kMaxCols) text_cols_ = kMaxCols;

  visible_text_rows = (gr_fb_height() - (kMarginHeight * 2)) / char_height_;
  return true;
}

bool WearRecoveryUI::Init(const std::string& locale) {
  if (!ScreenRecoveryUI::Init(locale)) {
    return false;
  }

  LoadBitmap("icon_error", &backgroundIcon[ERROR]);
  backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR];

  // This leaves backgroundIcon[INSTALLING_UPDATE] and backgroundIcon[ERASING]
  // as NULL which is fine since draw_background_locked() doesn't use them.

  return true;
}

void WearRecoveryUI::SetStage(int current, int max) {
}

void WearRecoveryUI::Print(const char* fmt, ...) {
  char buf[256];
  va_list ap;
  va_start(ap, fmt);
  vsnprintf(buf, 256, fmt, ap);
  va_end(ap);

  fputs(buf, stdout);

  // This can get called before ui_init(), so be careful.
  pthread_mutex_lock(&updateMutex);
  if (text_rows_ > 0 && text_cols_ > 0) {
    char* ptr;
    for (ptr = buf; *ptr != '\0'; ++ptr) {
      if (*ptr == '\n' || text_col_ >= text_cols_) {
        text_[text_row_][text_col_] = '\0';
        text_col_ = 0;
        text_row_ = (text_row_ + 1) % text_rows_;
        if (text_row_ == text_top_) text_top_ = (text_top_ + 1) % text_rows_;
      }
      if (*ptr != '\n') text_[text_row_][text_col_++] = *ptr;
    }
    text_[text_row_][text_col_] = '\0';
    update_screen_locked();
  }
  pthread_mutex_unlock(&updateMutex);
}

void WearRecoveryUI::StartMenu(const char* const* headers, const char* const* items,
                               int initial_selection) {
  pthread_mutex_lock(&updateMutex);
  if (text_rows_ > 0 && text_cols_ > 0) {
    menu_headers_ = headers;
    size_t i = 0;
    // "i < text_rows_" is removed from the loop termination condition,
    // which is different from the one in ScreenRecoveryUI::StartMenu().
    // Because WearRecoveryUI supports scrollable menu, it's fine to have
    // more entries than text_rows_. The menu may be truncated otherwise.
    // Bug: 23752519
    for (; items[i] != nullptr; i++) {
      strncpy(menu_[i], items[i], text_cols_ - 1);
      menu_[i][text_cols_ - 1] = '\0';
    }
    menu_items = i;
    show_menu = true;
    menu_sel = initial_selection;
    menu_start = 0;
    menu_end = visible_text_rows - 1 - kMenuUnusableRows;
    if (menu_items <= menu_end) menu_end = menu_items;
    update_screen_locked();
  }
  pthread_mutex_unlock(&updateMutex);
}

int WearRecoveryUI::SelectMenu(int sel) {
  int old_sel;
  pthread_mutex_lock(&updateMutex);
  if (show_menu) {
    old_sel = menu_sel;
    menu_sel = sel;
    if (menu_sel < 0) menu_sel = 0;
    if (menu_sel >= menu_items) menu_sel = menu_items - 1;
    if (menu_sel < menu_start) {
      menu_start--;
      menu_end--;
    } else if (menu_sel >= menu_end && menu_sel < menu_items) {
      menu_end++;
      menu_start++;
    }
    sel = menu_sel;
    if (menu_sel != old_sel) update_screen_locked();
  }
  pthread_mutex_unlock(&updateMutex);
  return sel;
}

void WearRecoveryUI::ShowFile(FILE* fp) {
  std::vector<off_t> offsets;
  offsets.push_back(ftello(fp));
  ClearText();

  struct stat sb;
  fstat(fileno(fp), &sb);

  bool show_prompt = false;
  while (true) {
    if (show_prompt) {
      Print("--(%d%% of %d bytes)--",
            static_cast<int>(100 * (double(ftello(fp)) / double(sb.st_size))),
            static_cast<int>(sb.st_size));
      Redraw();
      while (show_prompt) {
        show_prompt = false;
        int key = WaitKey();
        if (key == KEY_POWER || key == KEY_ENTER) {
          return;
        } else if (key == KEY_UP || key == KEY_VOLUMEUP) {
          if (offsets.size() <= 1) {
            show_prompt = true;
          } else {
            offsets.pop_back();
            fseek(fp, offsets.back(), SEEK_SET);
          }
        } else {
          if (feof(fp)) {
            return;
          }
          offsets.push_back(ftello(fp));
        }
      }
      ClearText();
    }

    int ch = getc(fp);
    if (ch == EOF) {
      text_row_ = text_top_ = text_rows_ - 2;
      show_prompt = true;
    } else {
      PutChar(ch);
      if (text_col_ == 0 && text_row_ >= text_rows_ - 2) {
        text_top_ = text_row_;
        show_prompt = true;
      }
    }
  }
}

void WearRecoveryUI::PutChar(char ch) {
  pthread_mutex_lock(&updateMutex);
  if (ch != '\n') text_[text_row_][text_col_++] = ch;
  if (ch == '\n' || text_col_ >= text_cols_) {
    text_col_ = 0;
    ++text_row_;
  }
  pthread_mutex_unlock(&updateMutex);
}

void WearRecoveryUI::ShowFile(const char* filename) {
  FILE* fp = fopen_path(filename, "re");
  if (fp == nullptr) {
    Print("  Unable to open %s: %s\n", filename, strerror(errno));
    return;
  }
  ShowFile(fp);
  fclose(fp);
}

void WearRecoveryUI::PrintOnScreenOnly(const char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  PrintV(fmt, false, ap);
  va_end(ap);
}

void WearRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) {
  std::string str;
  android::base::StringAppendV(&str, fmt, ap);

  if (copy_to_stdout) {
    fputs(str.c_str(), stdout);
  }

  pthread_mutex_lock(&updateMutex);
  if (text_rows_ > 0 && text_cols_ > 0) {
    for (const char* ptr = str.c_str(); *ptr != '\0'; ++ptr) {
      if (*ptr == '\n' || text_col_ >= text_cols_) {
        text_[text_row_][text_col_] = '\0';
        text_col_ = 0;
        text_row_ = (text_row_ + 1) % text_rows_;
        if (text_row_ == text_top_) text_top_ = (text_top_ + 1) % text_rows_;
      }
      if (*ptr != '\n') text_[text_row_][text_col_++] = *ptr;
    }
    text_[text_row_][text_col_] = '\0';
    update_screen_locked();
  }
  pthread_mutex_unlock(&updateMutex);
}
