text: from __future__ import absolute_import
  
  import datetime
  
  from .config import get_config_file_paths
  from .util import *
  
  # config file path
  GOALS_CONFIG_FILE_PATH = get_config_file_paths()["GOALS_CONFIG_FILE_PATH"]
  GOALS_CONFIG_FOLDER_PATH = get_folder_path_from_file_path(GOALS_CONFIG_FILE_PATH)
  
  
  def strike(text):
      """
      strikethrough text
      :param text:
      :return:
      """
      return u"\u0336".join(text) + u"\u0336"
  
  
  def get_goal_file_path(goal_name):
      return GOALS_CONFIG_FOLDER_PATH + "/" + goal_name + ".yaml"
  
  
  def process(input):
      """
      the main process
      :param input:
      """
      _input = input.lower().strip()
      check_sub_command(_input)
  
  
  def check_sub_command(c):
      """
      command checker
      :param c:
      :return:
      """
      sub_commands = {
          "new": new_goal,
          "tasks": view_related_tasks,
          "view": list_goals,
          "complete": complete_goal,
          "analyze": goals_analysis,
      }
      try:
          return sub_commands[c]()
      except KeyError:
          click.echo(chalk.red("Command does not exist!"))
          click.echo('Try "yoda goals --help" for more info')
  
  
  def goals_dir_check():
      """
      check if goals directory exists. If not, create
      """
      if not os.path.exists(GOALS_CONFIG_FOLDER_PATH):
          try:
              os.makedirs(GOALS_CONFIG_FOLDER_PATH)
          except OSError as exc:  # Guard against race condition
              if exc.errno != errno.EEXIST:
                  raise
  
  
  def append_data_into_file(data, file_path):
      """
      append data into existing file
      :param data:
      :param file_path:
      """
      with open(file_path) as file:
          # read contents
          contents = yaml.load(file)
          contents["entries"].append(data)
  
          # enter data
          with open(file_path, "w") as file:
              yaml.dump(contents, file, default_flow_style=False)
  
  
  def complete_goal():
      """
      complete a goal
      """
      not_valid_goal_number = 1
      if os.path.isfile(GOALS_CONFIG_FILE_PATH):
          with open(GOALS_CONFIG_FILE_PATH) as todays_tasks_entry:
              contents = yaml.load(todays_tasks_entry)
              no_goal_left = True
              for entry in contents["entries"]:
                  if entry["status"] == 0:
                      no_goal_left = False
  
              if no_goal_left:
                  click.echo(
                      chalk.green(
                          'All goals have been completed! Add a new goal by entering "yoda goals new"'
                      )
                  )
              else:
                  click.echo("Goals:")
                  click.echo("----------------")
                  click.echo("Number |  Deadline   | Goal")
                  click.echo("-------|-------------|-----")
  
                  for i, entry in enumerate(contents["entries"]):
                      deadline = entry["deadline"]
                      text = (
                          entry["text"] if entry["status"] == 0 else strike(entry["text"])
                      )
                      if entry["status"] == 0:
                          click.echo("   " + str(i) + "   | " + deadline + "  | " + text)
                  while not_valid_goal_number:
                      click.echo(
                          chalk.blue(
                              "Enter the goal number that you would like to set as completed"
                          )
                      )
                      goal_to_be_completed = int(input())
                      if goal_to_be_completed > len(contents["entries"]):
                          click.echo(chalk.red("Please Enter a valid goal number!"))
                      else:
                          contents["entries"][goal_to_be_completed - 1]["status"] = 1
                          input_data(contents, GOALS_CONFIG_FILE_PATH)
                          not_valid_goal_number = 0
      else:
          click.echo(
              chalk.red(
                  'There are no goals set. Set a new goal by entering "yoda goals new"'
              )
          )
  
  
  def goal_name_exists(goal_name):
      file_name = get_goal_file_path(goal_name)
      return os.path.isfile(file_name)
  
  
  def new_goal():
      """
      new goal
      """
  
      goals_dir_check()
  
      goal_name_not_ok = True
  
      click.echo(chalk.blue("Input a single-word name of the goal:"))
      while goal_name_not_ok:
          goal_name = input().strip()
          if goal_name.isalnum():
              goal_name_not_ok = False
          else:
              click.echo(
                  chalk.red(
                      "Only alphanumeric characters can be used! Please input the goal name:"
                  )
              )
  
      if goal_name_exists(goal_name):
          click.echo(
              chalk.red(
                  'A goal with this name already exists. Please type "yoda goals view" to see a list of existing goals'
              )
          )
      else:
          click.echo(chalk.blue("Input description of the goal:"))
          text = input().strip()
  
          click.echo(chalk.blue("Input due date for the goal (YYYY-MM-DD):"))
          incorrect_date_format = True
          while incorrect_date_format:
              deadline = input().strip()
              try:
                  date_str = datetime.datetime.strptime(deadline, "%Y-%m-%d").strftime(
                      "%Y-%m-%d"
                  )
                  if date_str != deadline:
                      raise ValueError
                  incorrect_date_format = False
              except ValueError:
                  click.echo(
                      chalk.red(
                          "Incorrect data format, should be YYYY-MM-DD. Please repeat:"
                      )
                  )
  
          if os.path.isfile(GOALS_CONFIG_FILE_PATH):
              setup_data = dict(name=goal_name, text=text, deadline=deadline, status=0)
              append_data_into_file(setup_data, GOALS_CONFIG_FILE_PATH)
          else:
              setup_data = dict(
                  entries=[dict(name=goal_name, text=text, deadline=deadline, status=0)]
              )
              input_data(setup_data, GOALS_CONFIG_FILE_PATH)
  
          input_data(dict(entries=[]), get_goal_file_path(goal_name))
  
  
  def goals_analysis():
      """
      goals alysis
      """
  
      now = datetime.datetime.now()
  
      total_goals = 0
      total_incomplete_goals = 0
      total_missed_goals = 0
      total_goals_next_week = 0
      total_goals_next_month = 0
  
      if os.path.isfile(GOALS_CONFIG_FILE_PATH):
          with open(GOALS_CONFIG_FILE_PATH) as goals_file:
              contents = yaml.load(goals_file)
              for entry in contents["entries"]:
                  total_goals += 1
                  if entry["status"] == 0:
                      total_incomplete_goals += 1
                      deadline = datetime.datetime.strptime(entry["deadline"], "%Y-%m-%d")
                      total_missed_goals += 1 if deadline < now else 0
                      total_goals_next_week += 1 if (deadline - now).days <= 7 else 0
                      total_goals_next_month += 1 if (deadline - now).days <= 30 else 0
          percent_incomplete_goals = total_incomplete_goals * 100 / total_goals
          percent_complete_goals = 100 - percent_incomplete_goals
  
          click.echo(
              chalk.red(
                  "Percentage of incomplete goals : " + str(percent_incomplete_goals)
              )
          )
          click.echo(
              chalk.green(
                  "Percentage of completed goals : " + str(percent_complete_goals)
              )
          )
          click.echo(
              chalk.blue("Number of missed deadlines : " + str(total_missed_goals))
          )
          click.echo(
              chalk.blue(
                  "Number of goals due within the next week : "
                  + str(total_goals_next_week)
              )
          )
          click.echo(
              chalk.blue(
                  "Number of goals due within the next month : "
                  + str(total_goals_next_month)
              )
          )
  
      else:
          click.echo(
              chalk.red(
                  'There are no goals set. Set a new goal by entering "yoda goals new"'
              )
          )
  
  
  def add_task_to_goal(goal_name, date, timestamp):
      goal_filename = get_goal_file_path(goal_name)
      if os.path.isfile(goal_filename):
          setup_data = dict(date=date, timestamp=timestamp)
          append_data_into_file(setup_data, goal_filename)
          return True
      return False
  
  
  def list_goals():
      """
      get goals listed chronologically by deadlines
      """
      if os.path.isfile(GOALS_CONFIG_FILE_PATH):
  
          with open(GOALS_CONFIG_FILE_PATH) as goals_file:
              contents = yaml.load(goals_file)
  
              if len(contents):
                  contents["entries"].sort(key=lambda x: x["deadline"].split("-"))
  
                  click.echo("Goals")
                  click.echo("----------------")
                  click.echo("Status |  Deadline   | Name: text")
                  click.echo("-------|-------------|---------------")
                  incomplete_goals = 0
                  total_tasks = 0
                  total_missed_deadline = 0
  
                  for entry in contents["entries"]:
                      total_tasks += 1
                      incomplete_goals += 1 if entry["status"] == 0 else 0
                      deadline = entry["deadline"]
                      name = entry["name"]
                      text = (
                          entry["text"] if entry["status"] == 0 else strike(entry["text"])
                      )
                      status = "O" if entry["status"] == 0 else "X"
  
                      deadline_time = datetime.datetime.strptime(deadline, "%Y-%m-%d")
                      now = datetime.datetime.now()
  
                      total_missed_deadline += 1 if deadline_time < now else 0
  
                      click.echo(
                          "   "
                          + status
                          + "   | "
                          + deadline
                          + "  | #"
                          + name
                          + ": "
                          + text
                      )
  
                  click.echo("----------------")
                  click.echo("")
                  click.echo("Summary:")
                  click.echo("----------------")
  
                  if incomplete_goals == 0:
                      click.echo(
                          chalk.green(
                              'All goals have been completed! Set a new goal by entering "yoda goals new"'
                          )
                      )
                  else:
                      click.echo(chalk.red("Incomplete tasks: " + str(incomplete_goals)))
                      click.echo(
                          chalk.red(
                              "Tasks with missed deadline: " + str(total_missed_deadline)
                          )
                      )
                      click.echo(
                          chalk.green(
                              "Completed tasks: " + str(total_tasks - incomplete_goals)
                          )
                      )
  
              else:
                  click.echo(
                      'There are no goals set. Set a new goal by entering "yoda goals new"'
                  )
  
      else:
          click.echo(
              'There are no goals set. Set a new goal by entering "yoda goals new"'
          )
  
  
  def view_related_tasks():
      """
      list tasks assigned to the goal
      """
  
      from .diary import get_task_info
  
      not_valid_name = True
  
      if os.path.isfile(GOALS_CONFIG_FILE_PATH):
          while not_valid_name:
              click.echo(chalk.blue("Enter the goal name that you would like to examine"))
              goal_name = input()
              goal_file_name = get_goal_file_path(goal_name)
              if os.path.isfile(goal_file_name):
                  not_valid_name = False
  
          with open(goal_file_name) as goals_file:
              contents = yaml.load(goals_file)
  
              if len(contents["entries"]):
  
                  total_tasks = 0
                  total_incomplete = 0
  
                  click.echo("Tasks assigned to the goal:")
                  click.echo("----------------")
                  click.echo("Status |  Date   | Text")
                  click.echo("-------|---------|-----")
  
                  for entry in contents["entries"]:
                      timestamp = entry["timestamp"]
                      date = entry["date"]
                      status, text = get_task_info(timestamp, date)
                      total_tasks += 1
                      total_incomplete += 1 if status == 0 else 0
  
                      text = text if status == 0 else strike(text)
                      status = "O" if status == 0 else "X"
                      click.echo("   " + status + "   | " + date + "| " + text)
  
                  click.echo("----------------")
                  click.echo("")
                  click.echo("Summary:")
                  click.echo("----------------")
  
                  click.echo(
                      chalk.red(
                          "Incomplete tasks assigned to the goal: "
                          + str(total_incomplete)
                      )
                  )
                  click.echo(
                      chalk.green(
                          "Completed tasks assigned to the goal: "
                          + str(total_tasks - total_incomplete)
                      )
                  )
  
              else:
                  click.echo(
                      chalk.red(
                          'There are no tasks assigned to the goal. Add a new task by entering "yoda diary nt"'
                      )
                  )
  
      else:
          click.echo(
              chalk.red(
                  'There are no goals set. Set a new goal by entering "yoda goals new"'
              )
          )
  