# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals

import frappe, json
from frappe import _
import frappe.permissions
import re, csv, os, sys
from frappe.utils.csvutils import UnicodeWriter
from frappe.utils import cstr, formatdate, format_datetime
from frappe.core.doctype.data_import.importer import get_data_keys
from six import string_types

reflags = {
	"I":re.I,
	"L":re.L,
	"M":re.M,
	"U":re.U,
	"S":re.S,
	"X":re.X,
	"D": re.DEBUG
}

@frappe.whitelist()
def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data="No", select_columns=None,
	from_data_import="No", excel_format="No"):
	all_doctypes = all_doctypes=="Yes"
	if select_columns:
		select_columns = json.loads(select_columns);
	docs_to_export = {}
	if doctype:
		if isinstance(doctype, string_types):
			doctype = [doctype];
		if len(doctype) > 1:
			docs_to_export = doctype[1]
		doctype = doctype[0]

	if not parent_doctype:
		parent_doctype = doctype

	column_start_end = {}

	if all_doctypes:
		child_doctypes = []
		for df in frappe.get_meta(doctype).get_table_fields():
			child_doctypes.append(dict(doctype=df.options, parentfield=df.fieldname))

	def get_data_keys_definition():
		return get_data_keys()

	def add_main_header():
		w.writerow([_('Data Import Template')])
		w.writerow([get_data_keys_definition().main_table, doctype])

		if parent_doctype != doctype:
			w.writerow([get_data_keys_definition().parent_table, parent_doctype])
		else:
			w.writerow([''])

		w.writerow([''])
		w.writerow([_('Notes:')])
		w.writerow([_('Please do not change the template headings.')])
		w.writerow([_('First data column must be blank.')])
		w.writerow([_('If you are uploading new records, leave the "name" (ID) column blank.')])
		w.writerow([_('If you are uploading new records, "Naming Series" becomes mandatory, if present.')])
		w.writerow([_('Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.')])
		w.writerow([_('For updating, you can update only selective columns.')])
		w.writerow([_('You can only upload upto 5000 records in one go. (may be less in some cases)')])
		if key == "parent":
			w.writerow([_('"Parent" signifies the parent table in which this row must be added')])
			w.writerow([_('If you are updating, please select "Overwrite" else existing rows will not be deleted.')])

	def build_field_columns(dt, parentfield=None):
		meta = frappe.get_meta(dt)

		# build list of valid docfields
		tablecolumns = []
		for f in frappe.db.sql('desc `tab%s`' % dt):
			field = meta.get_field(f[0])
			if field and ((select_columns and f[0] in select_columns[dt]) or not select_columns):
				tablecolumns.append(field)

		tablecolumns.sort(key = lambda a: int(a.idx))

		_column_start_end = frappe._dict(start=0)

		if dt==doctype:
			_column_start_end = frappe._dict(start=0)
		else:
			_column_start_end = frappe._dict(start=len(columns))

			append_field_column(frappe._dict({
				"fieldname": "name",
				"parent": dt,
				"label": "ID",
				"fieldtype": "Data",
				"reqd": 1,
				"idx": 0,
				"info": _("Leave blank for new records")
			}), True)

		for docfield in tablecolumns:
			append_field_column(docfield, True)

		# all non mandatory fields
		for docfield in tablecolumns:
			append_field_column(docfield, False)

		# if there is one column, add a blank column (?)
		if len(columns)-_column_start_end.start == 1:
			append_empty_field_column()

		# append DocType name
		tablerow[_column_start_end.start + 1] = dt

		if parentfield:
			tablerow[_column_start_end.start + 2] = parentfield

		_column_start_end.end = len(columns) + 1

		column_start_end[(dt, parentfield)] = _column_start_end

	def append_field_column(docfield, for_mandatory):
		if not docfield:
			return
		if for_mandatory and not docfield.reqd:
			return
		if not for_mandatory and docfield.reqd:
			return
		if docfield.fieldname in ('parenttype', 'trash_reason'):
			return
		if docfield.hidden:
			return
		if select_columns and docfield.fieldname not in select_columns.get(docfield.parent, []):
			return

		tablerow.append("")
		fieldrow.append(docfield.fieldname)
		labelrow.append(_(docfield.label))
		mandatoryrow.append(docfield.reqd and 'Yes' or 'No')
		typerow.append(docfield.fieldtype)
		inforow.append(getinforow(docfield))
		columns.append(docfield.fieldname)

	def append_empty_field_column():
		tablerow.append("~")
		fieldrow.append("~")
		labelrow.append("")